@roomi-fields/notebooklm-mcp 1.3.6 → 1.5.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 (284) hide show
  1. package/LICENSE +22 -22
  2. package/README.md +71 -34
  3. package/deployment/INDEX.md +292 -0
  4. package/deployment/PACKAGE-FILES.txt +180 -0
  5. package/deployment/QUICK-START.md +100 -0
  6. package/deployment/docs/01-INSTALL.md +611 -0
  7. package/deployment/docs/02-CONFIGURATION.md +404 -0
  8. package/deployment/docs/03-API.md +1691 -0
  9. package/deployment/docs/04-N8N-INTEGRATION.md +373 -0
  10. package/deployment/docs/05-TROUBLESHOOTING.md +429 -0
  11. package/deployment/docs/06-NOTEBOOK-LIBRARY.md +692 -0
  12. package/deployment/docs/07-AUTO-DISCOVERY.md +236 -0
  13. package/deployment/docs/08-WSL-USAGE.md +363 -0
  14. package/deployment/docs/09-MULTI-INTERFACE.md +293 -0
  15. package/deployment/docs/10-CONTENT-MANAGEMENT.md +421 -0
  16. package/deployment/docs/11-MULTI-ACCOUNT.md +295 -0
  17. package/deployment/docs/README.md +207 -0
  18. package/deployment/scripts/README.md +564 -0
  19. package/deployment/scripts/install.ps1 +114 -0
  20. package/deployment/scripts/setup-auth.ps1 +217 -0
  21. package/deployment/scripts/start-server.ps1 +72 -0
  22. package/deployment/scripts/stop-server.ps1 +51 -0
  23. package/deployment/scripts/test-api.ps1 +651 -0
  24. package/deployment/scripts/test-auth.ps1 +323 -0
  25. package/deployment/scripts/test-auto-discovery.ps1 +295 -0
  26. package/deployment/scripts/test-cors.ps1 +398 -0
  27. package/deployment/scripts/test-errors.ps1 +581 -0
  28. package/deployment/scripts/test-server.ps1 +140 -0
  29. package/deployment/scripts/test-sessions.ps1 +426 -0
  30. package/deployment/scripts/test-validation.ps1 +299 -0
  31. package/dist/accounts/account-manager.d.ts +163 -0
  32. package/dist/accounts/account-manager.d.ts.map +1 -0
  33. package/dist/accounts/account-manager.js +614 -0
  34. package/dist/accounts/account-manager.js.map +1 -0
  35. package/dist/accounts/auto-login-manager.d.ts +62 -0
  36. package/dist/accounts/auto-login-manager.d.ts.map +1 -0
  37. package/dist/accounts/auto-login-manager.js +537 -0
  38. package/dist/accounts/auto-login-manager.js.map +1 -0
  39. package/dist/accounts/crypto.d.ts +45 -0
  40. package/dist/accounts/crypto.d.ts.map +1 -0
  41. package/dist/accounts/crypto.js +138 -0
  42. package/dist/accounts/crypto.js.map +1 -0
  43. package/dist/accounts/index.d.ts +14 -0
  44. package/dist/accounts/index.d.ts.map +1 -0
  45. package/dist/accounts/index.js +14 -0
  46. package/dist/accounts/index.js.map +1 -0
  47. package/dist/accounts/types.d.ts +103 -0
  48. package/dist/accounts/types.d.ts.map +1 -0
  49. package/dist/accounts/types.js +7 -0
  50. package/dist/accounts/types.js.map +1 -0
  51. package/dist/auth/auth-manager.d.ts +9 -2
  52. package/dist/auth/auth-manager.d.ts.map +1 -1
  53. package/dist/auth/auth-manager.js +60 -6
  54. package/dist/auth/auth-manager.js.map +1 -1
  55. package/dist/auto-discovery/auto-discovery.d.ts.map +1 -1
  56. package/dist/auto-discovery/auto-discovery.js +2 -1
  57. package/dist/auto-discovery/auto-discovery.js.map +1 -1
  58. package/dist/cli/accounts.d.ts +13 -0
  59. package/dist/cli/accounts.d.ts.map +1 -0
  60. package/dist/cli/accounts.js +195 -0
  61. package/dist/cli/accounts.js.map +1 -0
  62. package/dist/config.d.ts +1 -0
  63. package/dist/config.d.ts.map +1 -1
  64. package/dist/config.js +24 -0
  65. package/dist/config.js.map +1 -1
  66. package/dist/content/content-generator.d.ts +153 -0
  67. package/dist/content/content-generator.d.ts.map +1 -0
  68. package/dist/content/content-generator.js +637 -0
  69. package/dist/content/content-generator.js.map +1 -0
  70. package/dist/content/content-manager.d.ts +364 -0
  71. package/dist/content/content-manager.d.ts.map +1 -0
  72. package/dist/content/content-manager.js +3841 -0
  73. package/dist/content/content-manager.js.map +1 -0
  74. package/dist/content/content-templates.d.ts +183 -0
  75. package/dist/content/content-templates.d.ts.map +1 -0
  76. package/dist/content/content-templates.js +719 -0
  77. package/dist/content/content-templates.js.map +1 -0
  78. package/dist/content/index.d.ts +14 -0
  79. package/dist/content/index.d.ts.map +1 -0
  80. package/dist/content/index.js +14 -0
  81. package/dist/content/index.js.map +1 -0
  82. package/dist/content/types.d.ts +285 -0
  83. package/dist/content/types.d.ts.map +1 -0
  84. package/dist/content/types.js +10 -0
  85. package/dist/content/types.js.map +1 -0
  86. package/dist/errors.d.ts +1 -1
  87. package/dist/errors.d.ts.map +1 -1
  88. package/dist/errors.js.map +1 -1
  89. package/dist/http-wrapper.d.ts +7 -0
  90. package/dist/http-wrapper.d.ts.map +1 -1
  91. package/dist/http-wrapper.js +449 -29
  92. package/dist/http-wrapper.js.map +1 -1
  93. package/dist/i18n/en.json +120 -0
  94. package/dist/i18n/fr.json +120 -0
  95. package/dist/i18n/index.d.ts +168 -0
  96. package/dist/i18n/index.d.ts.map +1 -0
  97. package/dist/i18n/index.js +213 -0
  98. package/dist/i18n/index.js.map +1 -0
  99. package/dist/index.js +26 -2
  100. package/dist/index.js.map +1 -1
  101. package/dist/library/notebook-library.d.ts +4 -0
  102. package/dist/library/notebook-library.d.ts.map +1 -1
  103. package/dist/library/notebook-library.js +20 -3
  104. package/dist/library/notebook-library.js.map +1 -1
  105. package/dist/session/browser-session.d.ts +35 -8
  106. package/dist/session/browser-session.d.ts.map +1 -1
  107. package/dist/session/browser-session.js +243 -28
  108. package/dist/session/browser-session.js.map +1 -1
  109. package/dist/session/session-manager.d.ts +6 -0
  110. package/dist/session/session-manager.d.ts.map +1 -1
  111. package/dist/session/session-manager.js +46 -14
  112. package/dist/session/session-manager.js.map +1 -1
  113. package/dist/session/shared-context-manager.d.ts +3 -3
  114. package/dist/session/shared-context-manager.d.ts.map +1 -1
  115. package/dist/session/shared-context-manager.js +10 -7
  116. package/dist/session/shared-context-manager.js.map +1 -1
  117. package/dist/stdio-http-proxy.d.ts +24 -0
  118. package/dist/stdio-http-proxy.d.ts.map +1 -0
  119. package/dist/stdio-http-proxy.js +592 -0
  120. package/dist/stdio-http-proxy.js.map +1 -0
  121. package/dist/tools/index.d.ts +106 -1
  122. package/dist/tools/index.d.ts.map +1 -1
  123. package/dist/tools/index.js +1028 -7
  124. package/dist/tools/index.js.map +1 -1
  125. package/dist/types.d.ts +81 -17
  126. package/dist/types.d.ts.map +1 -1
  127. package/dist/utils/citation-extractor.d.ts +66 -0
  128. package/dist/utils/citation-extractor.d.ts.map +1 -0
  129. package/dist/utils/citation-extractor.js +492 -0
  130. package/dist/utils/citation-extractor.js.map +1 -0
  131. package/dist/utils/page-utils.d.ts +8 -0
  132. package/dist/utils/page-utils.d.ts.map +1 -1
  133. package/dist/utils/page-utils.js +112 -8
  134. package/dist/utils/page-utils.js.map +1 -1
  135. package/docs/ADDING_A_LANGUAGE.md +209 -0
  136. package/docs/ARCHITECTURE_MIGRATION_STUDY.md +894 -0
  137. package/docs/CHROME_PROFILE_LIMITATION.md +15 -1
  138. package/docs/MULTI_ACCOUNT_SYSTEM.md +304 -0
  139. package/package.json +15 -12
  140. package/scripts/archive/add-and-activate-notebook.ps1 +31 -0
  141. package/scripts/archive/add-new-notebook.ps1 +25 -0
  142. package/scripts/archive/add-rom1pey.ps1 +2 -0
  143. package/scripts/archive/add-rpmonster.ps1 +2 -0
  144. package/scripts/archive/add-source-debug.ps1 +11 -0
  145. package/scripts/archive/add-source-e2e.ps1 +28 -0
  146. package/scripts/archive/add-source-visible.ps1 +11 -0
  147. package/scripts/archive/add-test-notebook.ps1 +13 -0
  148. package/scripts/archive/add-test-source.ps1 +50 -0
  149. package/scripts/archive/capture-screen.ps1 +11 -0
  150. package/scripts/archive/change-language.mjs +45 -0
  151. package/scripts/archive/change-language.ts +44 -0
  152. package/scripts/archive/check-account.ps1 +19 -0
  153. package/scripts/archive/check-notebook-2.ps1 +8 -0
  154. package/scripts/archive/check-test-notebook.ps1 +11 -0
  155. package/scripts/archive/create-notebook-auto.ps1 +31 -0
  156. package/scripts/archive/create-notebook.ps1 +8 -0
  157. package/scripts/archive/create-rom1pey-notebook.ps1 +19 -0
  158. package/scripts/archive/create-rom1pey.ps1 +8 -0
  159. package/scripts/archive/create-test-notebook-fresh.ps1 +21 -0
  160. package/scripts/archive/create-test-notebook.ps1 +16 -0
  161. package/scripts/archive/debug-add-source-auto.ps1 +29 -0
  162. package/scripts/archive/debug-add-source.ps1 +19 -0
  163. package/scripts/archive/debug-add-text-source.ps1 +47 -0
  164. package/scripts/archive/debug-home.ps1 +10 -0
  165. package/scripts/archive/debug-selectors.ps1 +55 -0
  166. package/scripts/archive/debug-sources-panel.ps1 +22 -0
  167. package/scripts/archive/debug-ui.ps1 +17 -0
  168. package/scripts/archive/discover-home.ps1 +26 -0
  169. package/scripts/archive/kill-automation-chrome.ps1 +37 -0
  170. package/scripts/archive/list-my-notebooks.ps1 +27 -0
  171. package/scripts/archive/navigate-home-visible.ps1 +23 -0
  172. package/scripts/archive/navigate-home.ps1 +15 -0
  173. package/scripts/archive/run-e2e-english.ps1 +111 -0
  174. package/scripts/archive/run-e2e-rom1pey-v2.ps1 +122 -0
  175. package/scripts/archive/run-e2e-rom1pey.ps1 +117 -0
  176. package/scripts/archive/setup-english-test.ps1 +36 -0
  177. package/scripts/archive/setup-test-notebook.ps1 +71 -0
  178. package/scripts/archive/simple-add-source.ps1 +14 -0
  179. package/scripts/archive/t10.ps1 +2 -0
  180. package/scripts/archive/t20.ps1 +4 -0
  181. package/scripts/archive/t30.ps1 +9 -0
  182. package/scripts/archive/t31.ps1 +11 -0
  183. package/scripts/archive/t32.ps1 +6 -0
  184. package/scripts/archive/t39.ps1 +5 -0
  185. package/scripts/archive/t40.ps1 +5 -0
  186. package/scripts/archive/t53.ps1 +12 -0
  187. package/scripts/archive/t54.ps1 +12 -0
  188. package/scripts/archive/t55.ps1 +11 -0
  189. package/scripts/archive/t9.ps1 +1 -0
  190. package/scripts/archive/test-access.ps1 +28 -0
  191. package/scripts/archive/test-add-delete-source.ps1 +64 -0
  192. package/scripts/archive/test-add-source-visible.ps1 +16 -0
  193. package/scripts/archive/test-add-source.ps1 +19 -0
  194. package/scripts/archive/test-add-text-debug.ps1 +28 -0
  195. package/scripts/archive/test-add-text-source.ps1 +8 -0
  196. package/scripts/archive/test-add-url-source.ps1 +7 -0
  197. package/scripts/archive/test-ask-ascii.ps1 +20 -0
  198. package/scripts/archive/test-ask-cnv.ps1 +20 -0
  199. package/scripts/archive/test-ask-headed.ps1 +51 -0
  200. package/scripts/archive/test-ask-ifs.ps1 +16 -0
  201. package/scripts/archive/test-ask-now.ps1 +24 -0
  202. package/scripts/archive/test-ask-real.ps1 +19 -0
  203. package/scripts/archive/test-ask-visible.ps1 +20 -0
  204. package/scripts/archive/test-create-notebook.ps1 +8 -0
  205. package/scripts/archive/test-create-then-add.ps1 +17 -0
  206. package/scripts/archive/test-delete-source.ps1 +41 -0
  207. package/scripts/archive/test-e2e-notebook.ps1 +21 -0
  208. package/scripts/archive/test-english-notebook.ps1 +20 -0
  209. package/scripts/archive/test-english.ps1 +7 -0
  210. package/scripts/archive/test-full-custom-instructions.ps1 +40 -0
  211. package/scripts/archive/test-full-infographic.ps1 +34 -0
  212. package/scripts/archive/test-full-language.ps1 +21 -0
  213. package/scripts/archive/test-full-presentation.ps1 +85 -0
  214. package/scripts/archive/test-full-report.ps1 +34 -0
  215. package/scripts/archive/test-full-source-selection.ps1 +35 -0
  216. package/scripts/archive/test-full-video-brief.ps1 +22 -0
  217. package/scripts/archive/test-full-video-explainer.ps1 +22 -0
  218. package/scripts/archive/test-full-video-styles.ps1 +37 -0
  219. package/scripts/archive/test-generate-report.ps1 +15 -0
  220. package/scripts/archive/test-generate-study-guide.ps1 +11 -0
  221. package/scripts/archive/test-headed-ask.ps1 +13 -0
  222. package/scripts/archive/test-headed-now.ps1 +9 -0
  223. package/scripts/archive/test-headed.ps1 +9 -0
  224. package/scripts/archive/test-hello.ps1 +7 -0
  225. package/scripts/archive/test-i18n-studio.ps1 +8 -0
  226. package/scripts/archive/test-i18n.ps1 +7 -0
  227. package/scripts/archive/test-manual-headed.ps1 +26 -0
  228. package/scripts/archive/test-mathieu-quota.ps1 +8 -0
  229. package/scripts/archive/test-notebook-1.ps1 +10 -0
  230. package/scripts/archive/test-notebook-2-sources.ps1 +12 -0
  231. package/scripts/archive/test-notebook1.ps1 +14 -0
  232. package/scripts/archive/test-personal-notebook.ps1 +14 -0
  233. package/scripts/archive/test-rate-limit.ps1 +19 -0
  234. package/scripts/archive/test-real-ask.ps1 +50 -0
  235. package/scripts/archive/test-real-ask2.ps1 +30 -0
  236. package/scripts/archive/test-rom1pey.ps1 +7 -0
  237. package/scripts/archive/test-rotation-complete.ps1 +14 -0
  238. package/scripts/archive/test-rotation.ps1 +8 -0
  239. package/scripts/archive/test-show-browser.ps1 +39 -0
  240. package/scripts/archive/test-update-notebook.ps1 +4 -0
  241. package/scripts/archive/verify-language-slow.ps1 +21 -0
  242. package/scripts/archive/verify-language.ps1 +15 -0
  243. package/scripts/check-server.ps1 +46 -0
  244. package/scripts/mcp-wsl-helper.sh +146 -0
  245. package/scripts/start-server.ps1 +94 -0
  246. package/scripts/stop-server.ps1 +30 -0
  247. package/scripts/switch-account-language.sh +191 -0
  248. package/scripts/test-account.ps1 +58 -0
  249. package/dist/__tests__/cleanup-manager.test.d.ts +0 -2
  250. package/dist/__tests__/cleanup-manager.test.d.ts.map +0 -1
  251. package/dist/__tests__/cleanup-manager.test.js +0 -341
  252. package/dist/__tests__/cleanup-manager.test.js.map +0 -1
  253. package/dist/__tests__/config-parsing.test.d.ts +0 -2
  254. package/dist/__tests__/config-parsing.test.d.ts.map +0 -1
  255. package/dist/__tests__/config-parsing.test.js +0 -338
  256. package/dist/__tests__/config-parsing.test.js.map +0 -1
  257. package/dist/__tests__/config.test.d.ts +0 -2
  258. package/dist/__tests__/config.test.d.ts.map +0 -1
  259. package/dist/__tests__/config.test.js +0 -267
  260. package/dist/__tests__/config.test.js.map +0 -1
  261. package/dist/__tests__/errors.test.d.ts +0 -2
  262. package/dist/__tests__/errors.test.d.ts.map +0 -1
  263. package/dist/__tests__/errors.test.js +0 -166
  264. package/dist/__tests__/errors.test.js.map +0 -1
  265. package/dist/__tests__/logger.test.d.ts +0 -2
  266. package/dist/__tests__/logger.test.d.ts.map +0 -1
  267. package/dist/__tests__/logger.test.js +0 -324
  268. package/dist/__tests__/logger.test.js.map +0 -1
  269. package/dist/__tests__/page-utils.test.d.ts +0 -2
  270. package/dist/__tests__/page-utils.test.d.ts.map +0 -1
  271. package/dist/__tests__/page-utils.test.js +0 -349
  272. package/dist/__tests__/page-utils.test.js.map +0 -1
  273. package/dist/__tests__/setup-verification.test.d.ts +0 -2
  274. package/dist/__tests__/setup-verification.test.d.ts.map +0 -1
  275. package/dist/__tests__/setup-verification.test.js +0 -15
  276. package/dist/__tests__/setup-verification.test.js.map +0 -1
  277. package/dist/__tests__/stealth-utils.test.d.ts +0 -2
  278. package/dist/__tests__/stealth-utils.test.d.ts.map +0 -1
  279. package/dist/__tests__/stealth-utils.test.js +0 -413
  280. package/dist/__tests__/stealth-utils.test.js.map +0 -1
  281. package/dist/__tests__/types.test.d.ts +0 -2
  282. package/dist/__tests__/types.test.d.ts.map +0 -1
  283. package/dist/__tests__/types.test.js +0 -461
  284. package/dist/__tests__/types.test.js.map +0 -1
@@ -0,0 +1,398 @@
1
+ #!/usr/bin/env pwsh
2
+ #Requires -Version 5.1
3
+
4
+ <#
5
+ .SYNOPSIS
6
+ CORS configuration testing script for NotebookLM MCP HTTP Server API
7
+
8
+ .DESCRIPTION
9
+ Tests CORS (Cross-Origin Resource Sharing) configuration:
10
+ - Default allowed origins (localhost ports)
11
+ - CORS headers in responses
12
+ - Preflight OPTIONS requests
13
+ - Origin header handling
14
+
15
+ .PARAMETER BaseUrl
16
+ Base URL of the server (default: http://localhost:3000)
17
+
18
+ .EXAMPLE
19
+ .\test-cors.ps1
20
+ Runs all CORS tests
21
+
22
+ .NOTES
23
+ Prerequisite: The server must be started
24
+ #>
25
+
26
+ param(
27
+ [string]$BaseUrl = "http://localhost:3000"
28
+ )
29
+
30
+ # Colors for logs
31
+ function Write-TestHeader {
32
+ param([string]$Message, [int]$Number, [int]$Total)
33
+ Write-Host "`n" -NoNewline
34
+ Write-Host "═══════════════════════════════════════════════════════" -ForegroundColor Magenta
35
+ Write-Host " [$Number/$Total] $Message" -ForegroundColor Cyan
36
+ Write-Host "═══════════════════════════════════════════════════════" -ForegroundColor Magenta
37
+ }
38
+
39
+ function Write-Success {
40
+ param([string]$Message)
41
+ Write-Host "✓ $Message" -ForegroundColor Green
42
+ }
43
+
44
+ function Write-Info {
45
+ param([string]$Message)
46
+ Write-Host "ℹ $Message" -ForegroundColor Yellow
47
+ }
48
+
49
+ function Write-ErrorUnexpected {
50
+ param([string]$Message)
51
+ Write-Host "✗ $Message" -ForegroundColor Red
52
+ }
53
+
54
+ # Banner
55
+ Clear-Host
56
+ Write-Host "`n" -NoNewline
57
+ Write-Host "╔════════════════════════════════════════════════════════╗" -ForegroundColor Magenta
58
+ Write-Host "║ ║" -ForegroundColor Magenta
59
+ Write-Host "║ CORS CONFIGURATION TESTS - HTTP API ║" -ForegroundColor Cyan
60
+ Write-Host "║ ║" -ForegroundColor Magenta
61
+ Write-Host "╚════════════════════════════════════════════════════════╝" -ForegroundColor Magenta
62
+ Write-Host ""
63
+
64
+ # Check that the server is accessible
65
+ Write-Host "Checking connection to server..." -ForegroundColor Yellow
66
+ try {
67
+ $null = Invoke-RestMethod -Uri "$BaseUrl/health" -TimeoutSec 5
68
+ Write-Success "Server accessible at $BaseUrl"
69
+ } catch {
70
+ Write-ErrorUnexpected "Unable to connect to server at $BaseUrl"
71
+ Write-Host "Make sure the server is started" -ForegroundColor Yellow
72
+ exit 1
73
+ }
74
+
75
+ $TotalTests = 10
76
+ $PassedTests = 0
77
+ $FailedTests = 0
78
+
79
+ # =============================================================================
80
+ # TEST 1: Request without Origin header (should work)
81
+ # =============================================================================
82
+ Write-TestHeader "Request without Origin header (same-origin)" 1 $TotalTests
83
+
84
+ try {
85
+ $response = Invoke-WebRequest -Uri "$BaseUrl/health" -Method Get -TimeoutSec 10
86
+
87
+ if ($response.StatusCode -eq 200) {
88
+ Write-Success "Request without Origin header accepted"
89
+ $PassedTests++
90
+ } else {
91
+ Write-ErrorUnexpected "Unexpected status code: $($response.StatusCode)"
92
+ $FailedTests++
93
+ }
94
+ } catch {
95
+ Write-ErrorUnexpected "Request failed: $($_.Exception.Message)"
96
+ $FailedTests++
97
+ }
98
+
99
+ # =============================================================================
100
+ # TEST 2: Request with allowed Origin (localhost:3000)
101
+ # =============================================================================
102
+ Write-TestHeader "Request with allowed Origin: localhost:3000" 2 $TotalTests
103
+
104
+ try {
105
+ $headers = @{ "Origin" = "http://localhost:3000" }
106
+ $response = Invoke-WebRequest -Uri "$BaseUrl/health" -Method Get -Headers $headers -TimeoutSec 10
107
+
108
+ $corsHeader = $response.Headers["Access-Control-Allow-Origin"]
109
+ if ($corsHeader -eq "http://localhost:3000" -or $corsHeader -eq "*") {
110
+ Write-Success "CORS header returned for allowed origin"
111
+ Write-Info "Access-Control-Allow-Origin: $corsHeader"
112
+ $PassedTests++
113
+ } else {
114
+ Write-ErrorUnexpected "Missing or incorrect CORS header: $corsHeader"
115
+ $FailedTests++
116
+ }
117
+ } catch {
118
+ Write-ErrorUnexpected "Request failed: $($_.Exception.Message)"
119
+ $FailedTests++
120
+ }
121
+
122
+ # =============================================================================
123
+ # TEST 3: Request with allowed Origin (localhost:5678 - n8n)
124
+ # =============================================================================
125
+ Write-TestHeader "Request with allowed Origin: localhost:5678 (n8n)" 3 $TotalTests
126
+
127
+ try {
128
+ $headers = @{ "Origin" = "http://localhost:5678" }
129
+ $response = Invoke-WebRequest -Uri "$BaseUrl/health" -Method Get -Headers $headers -TimeoutSec 10
130
+
131
+ $corsHeader = $response.Headers["Access-Control-Allow-Origin"]
132
+ if ($corsHeader -eq "http://localhost:5678" -or $corsHeader -eq "*") {
133
+ Write-Success "CORS header returned for n8n origin"
134
+ Write-Info "Access-Control-Allow-Origin: $corsHeader"
135
+ $PassedTests++
136
+ } else {
137
+ Write-ErrorUnexpected "Missing or incorrect CORS header: $corsHeader"
138
+ $FailedTests++
139
+ }
140
+ } catch {
141
+ Write-ErrorUnexpected "Request failed: $($_.Exception.Message)"
142
+ $FailedTests++
143
+ }
144
+
145
+ # =============================================================================
146
+ # TEST 4: Request with allowed Origin (127.0.0.1:3000)
147
+ # =============================================================================
148
+ Write-TestHeader "Request with allowed Origin: 127.0.0.1:3000" 4 $TotalTests
149
+
150
+ try {
151
+ $headers = @{ "Origin" = "http://127.0.0.1:3000" }
152
+ $response = Invoke-WebRequest -Uri "$BaseUrl/health" -Method Get -Headers $headers -TimeoutSec 10
153
+
154
+ $corsHeader = $response.Headers["Access-Control-Allow-Origin"]
155
+ if ($corsHeader -eq "http://127.0.0.1:3000" -or $corsHeader -eq "*") {
156
+ Write-Success "CORS header returned for 127.0.0.1 origin"
157
+ Write-Info "Access-Control-Allow-Origin: $corsHeader"
158
+ $PassedTests++
159
+ } else {
160
+ Write-ErrorUnexpected "Missing or incorrect CORS header: $corsHeader"
161
+ $FailedTests++
162
+ }
163
+ } catch {
164
+ Write-ErrorUnexpected "Request failed: $($_.Exception.Message)"
165
+ $FailedTests++
166
+ }
167
+
168
+ # =============================================================================
169
+ # TEST 5: Request with blocked Origin (external domain)
170
+ # =============================================================================
171
+ Write-TestHeader "Request with external Origin (should be blocked)" 5 $TotalTests
172
+
173
+ try {
174
+ $headers = @{ "Origin" = "https://malicious-site.com" }
175
+ $response = Invoke-WebRequest -Uri "$BaseUrl/health" -Method Get -Headers $headers -TimeoutSec 10
176
+
177
+ # Request should still succeed (CORS is browser-enforced), but check header
178
+ $corsHeader = $response.Headers["Access-Control-Allow-Origin"]
179
+
180
+ if ($null -eq $corsHeader -or $corsHeader -eq "") {
181
+ Write-Success "External origin correctly blocked (no CORS header)"
182
+ $PassedTests++
183
+ } elseif ($corsHeader -eq "https://malicious-site.com") {
184
+ Write-ErrorUnexpected "External origin was allowed! Security issue."
185
+ $FailedTests++
186
+ } else {
187
+ Write-Info "Response received, CORS header: $corsHeader"
188
+ # If wildcard is configured, this is expected
189
+ if ($corsHeader -eq "*") {
190
+ Write-Info "Wildcard CORS configured (intentional?)"
191
+ }
192
+ $PassedTests++
193
+ }
194
+ } catch {
195
+ # If blocked at server level, that's also acceptable
196
+ Write-Success "External origin request handled"
197
+ $PassedTests++
198
+ }
199
+
200
+ # =============================================================================
201
+ # TEST 6: OPTIONS preflight request
202
+ # =============================================================================
203
+ Write-TestHeader "OPTIONS preflight request" 6 $TotalTests
204
+
205
+ try {
206
+ $headers = @{
207
+ "Origin" = "http://localhost:3000"
208
+ "Access-Control-Request-Method" = "POST"
209
+ "Access-Control-Request-Headers" = "Content-Type"
210
+ }
211
+ $response = Invoke-WebRequest -Uri "$BaseUrl/health" -Method Options -Headers $headers -TimeoutSec 10
212
+
213
+ if ($response.StatusCode -eq 200 -or $response.StatusCode -eq 204) {
214
+ $allowMethods = $response.Headers["Access-Control-Allow-Methods"]
215
+ $allowHeaders = $response.Headers["Access-Control-Allow-Headers"]
216
+
217
+ Write-Success "Preflight request successful (status: $($response.StatusCode))"
218
+ if ($allowMethods) { Write-Info "Allow-Methods: $allowMethods" }
219
+ if ($allowHeaders) { Write-Info "Allow-Headers: $allowHeaders" }
220
+ $PassedTests++
221
+ } else {
222
+ Write-ErrorUnexpected "Unexpected status code: $($response.StatusCode)"
223
+ $FailedTests++
224
+ }
225
+ } catch {
226
+ Write-ErrorUnexpected "Preflight request failed: $($_.Exception.Message)"
227
+ $FailedTests++
228
+ }
229
+
230
+ # =============================================================================
231
+ # TEST 7: CORS headers include required methods
232
+ # =============================================================================
233
+ Write-TestHeader "CORS allows required HTTP methods" 7 $TotalTests
234
+
235
+ try {
236
+ $headers = @{
237
+ "Origin" = "http://localhost:3000"
238
+ "Access-Control-Request-Method" = "DELETE"
239
+ }
240
+ $response = Invoke-WebRequest -Uri "$BaseUrl/health" -Method Options -Headers $headers -TimeoutSec 10
241
+
242
+ $allowMethods = $response.Headers["Access-Control-Allow-Methods"]
243
+
244
+ if ($allowMethods) {
245
+ $requiredMethods = @("GET", "POST", "PUT", "DELETE")
246
+ $allPresent = $true
247
+
248
+ foreach ($method in $requiredMethods) {
249
+ if ($allowMethods -notlike "*$method*") {
250
+ Write-Info "Missing method: $method"
251
+ $allPresent = $false
252
+ }
253
+ }
254
+
255
+ if ($allPresent) {
256
+ Write-Success "All required HTTP methods allowed"
257
+ Write-Info "Methods: $allowMethods"
258
+ $PassedTests++
259
+ } else {
260
+ Write-ErrorUnexpected "Some required methods missing"
261
+ $FailedTests++
262
+ }
263
+ } else {
264
+ Write-ErrorUnexpected "No Access-Control-Allow-Methods header"
265
+ $FailedTests++
266
+ }
267
+ } catch {
268
+ Write-ErrorUnexpected "Request failed: $($_.Exception.Message)"
269
+ $FailedTests++
270
+ }
271
+
272
+ # =============================================================================
273
+ # TEST 8: CORS allows Content-Type header
274
+ # =============================================================================
275
+ Write-TestHeader "CORS allows Content-Type header" 8 $TotalTests
276
+
277
+ try {
278
+ $headers = @{
279
+ "Origin" = "http://localhost:3000"
280
+ "Access-Control-Request-Headers" = "Content-Type"
281
+ }
282
+ $response = Invoke-WebRequest -Uri "$BaseUrl/health" -Method Options -Headers $headers -TimeoutSec 10
283
+
284
+ $allowHeaders = $response.Headers["Access-Control-Allow-Headers"]
285
+
286
+ if ($allowHeaders -and $allowHeaders -like "*Content-Type*") {
287
+ Write-Success "Content-Type header allowed"
288
+ Write-Info "Allowed headers: $allowHeaders"
289
+ $PassedTests++
290
+ } else {
291
+ Write-ErrorUnexpected "Content-Type not in allowed headers: $allowHeaders"
292
+ $FailedTests++
293
+ }
294
+ } catch {
295
+ Write-ErrorUnexpected "Request failed: $($_.Exception.Message)"
296
+ $FailedTests++
297
+ }
298
+
299
+ # =============================================================================
300
+ # TEST 9: POST request with Origin header
301
+ # =============================================================================
302
+ Write-TestHeader "POST /ask with Origin header" 9 $TotalTests
303
+
304
+ try {
305
+ $headers = @{ "Origin" = "http://localhost:5678" }
306
+ $body = @{ question = "test" } | ConvertTo-Json
307
+
308
+ # This will likely fail due to auth, but we're testing CORS
309
+ $response = Invoke-WebRequest -Uri "$BaseUrl/ask" -Method Post -Headers $headers -Body $body -ContentType "application/json" -TimeoutSec 10
310
+
311
+ $corsHeader = $response.Headers["Access-Control-Allow-Origin"]
312
+ if ($corsHeader) {
313
+ Write-Success "CORS header present on POST response"
314
+ Write-Info "Access-Control-Allow-Origin: $corsHeader"
315
+ $PassedTests++
316
+ } else {
317
+ Write-ErrorUnexpected "No CORS header on POST response"
318
+ $FailedTests++
319
+ }
320
+ } catch {
321
+ # Check if CORS headers are present even on error responses
322
+ $errorResponse = $_.Exception.Response
323
+ if ($errorResponse) {
324
+ # PowerShell doesn't easily expose headers on error responses
325
+ # Consider this passed if we got a proper HTTP response
326
+ Write-Success "POST request handled (CORS checked at browser level)"
327
+ $PassedTests++
328
+ } else {
329
+ Write-ErrorUnexpected "Request failed completely: $($_.Exception.Message)"
330
+ $FailedTests++
331
+ }
332
+ }
333
+
334
+ # =============================================================================
335
+ # TEST 10: CORS allows Authorization header
336
+ # =============================================================================
337
+ Write-TestHeader "CORS allows Authorization header" 10 $TotalTests
338
+
339
+ try {
340
+ $headers = @{
341
+ "Origin" = "http://localhost:3000"
342
+ "Access-Control-Request-Headers" = "Authorization"
343
+ }
344
+ $response = Invoke-WebRequest -Uri "$BaseUrl/health" -Method Options -Headers $headers -TimeoutSec 10
345
+
346
+ $allowHeaders = $response.Headers["Access-Control-Allow-Headers"]
347
+
348
+ if ($allowHeaders -and $allowHeaders -like "*Authorization*") {
349
+ Write-Success "Authorization header allowed"
350
+ Write-Info "Allowed headers: $allowHeaders"
351
+ $PassedTests++
352
+ } else {
353
+ Write-Info "Authorization not explicitly listed (may still work)"
354
+ # Not critical - some setups don't need Authorization header
355
+ $PassedTests++
356
+ }
357
+ } catch {
358
+ Write-ErrorUnexpected "Request failed: $($_.Exception.Message)"
359
+ $FailedTests++
360
+ }
361
+
362
+ # =============================================================================
363
+ # FINAL SUMMARY
364
+ # =============================================================================
365
+ Write-Host "`n" -NoNewline
366
+ Write-Host "╔════════════════════════════════════════════════════════╗" -ForegroundColor Magenta
367
+ Write-Host "║ ║" -ForegroundColor Magenta
368
+ Write-Host "║ CORS TEST SUMMARY ║" -ForegroundColor Cyan
369
+ Write-Host "║ ║" -ForegroundColor Magenta
370
+ Write-Host "╚════════════════════════════════════════════════════════╝" -ForegroundColor Magenta
371
+ Write-Host ""
372
+
373
+ $TotalExecuted = $PassedTests + $FailedTests
374
+ $SuccessRate = if ($TotalExecuted -gt 0) { [math]::Round(($PassedTests / $TotalExecuted) * 100, 1) } else { 0 }
375
+
376
+ Write-Host "Total tests: $TotalTests" -ForegroundColor White
377
+ Write-Host "Tests passed: " -NoNewline -ForegroundColor White
378
+ Write-Host "$PassedTests" -ForegroundColor Green
379
+ Write-Host "Tests failed: " -NoNewline -ForegroundColor White
380
+ Write-Host "$FailedTests" -ForegroundColor $(if($FailedTests -gt 0){"Red"}else{"Green"})
381
+ Write-Host "Success rate: " -NoNewline -ForegroundColor White
382
+ Write-Host "$SuccessRate%" -ForegroundColor $(if($SuccessRate -eq 100){"Green"}elseif($SuccessRate -ge 80){"Yellow"}else{"Red"})
383
+
384
+ Write-Host ""
385
+
386
+ if ($FailedTests -eq 0) {
387
+ Write-Host "════════════════════════════════════════════════════════" -ForegroundColor Green
388
+ Write-Host " ✓ ALL CORS CONFIGURATION TESTS PASSED!" -ForegroundColor Green
389
+ Write-Host "════════════════════════════════════════════════════════" -ForegroundColor Green
390
+ exit 0
391
+ } else {
392
+ Write-Host "════════════════════════════════════════════════════════" -ForegroundColor Yellow
393
+ Write-Host " ⚠ SOME CORS TESTS FAILED" -ForegroundColor Yellow
394
+ Write-Host "════════════════════════════════════════════════════════" -ForegroundColor Yellow
395
+ Write-Host ""
396
+ Write-Host "See details above to identify the issues." -ForegroundColor Yellow
397
+ exit 1
398
+ }