documentation-hub 5.7.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 (271) hide show
  1. package/.eslintrc.json +43 -0
  2. package/.github/workflows/build.yml +64 -0
  3. package/.github/workflows/ci.yml +39 -0
  4. package/.vscode/extensions.json +3 -0
  5. package/Current.md +97 -0
  6. package/DocHub_Image.png +0 -0
  7. package/README.md +666 -0
  8. package/USER_GUIDE.md +1173 -0
  9. package/Updater.md +311 -0
  10. package/build/256x256.png +0 -0
  11. package/build/512x512.png +0 -0
  12. package/build/app-update.yml +4 -0
  13. package/build/create-icon.js +208 -0
  14. package/build/icon.ico +0 -0
  15. package/build/icon.png +0 -0
  16. package/build/icon_1024x1024.png +0 -0
  17. package/dist/assets/Analytics-BpsG9895.js +1 -0
  18. package/dist/assets/Card-IAZin8kp.js +1 -0
  19. package/dist/assets/CurrentSession-B-rFkHvf.js +12 -0
  20. package/dist/assets/Dashboard-C_5gMb0q.js +1 -0
  21. package/dist/assets/Documents-CqZ25axS.js +1 -0
  22. package/dist/assets/Input-l89xwXBi.js +1 -0
  23. package/dist/assets/Reporting-DqdHJY_a.js +1 -0
  24. package/dist/assets/Search-XNbu5z_3.js +1 -0
  25. package/dist/assets/SessionManager-lH9hZfzH.js +1 -0
  26. package/dist/assets/Sessions-ClZOPYNc.js +1 -0
  27. package/dist/assets/Settings-DUEHGURa.js +11 -0
  28. package/dist/assets/index-8xUe8ptc.js +24 -0
  29. package/dist/assets/index-RYyJqF7O.css +1 -0
  30. package/dist/assets/path-BkOl0AGO.js +1 -0
  31. package/dist/assets/promises-ID_B9S-h.js +1 -0
  32. package/dist/assets/urlHelpers-TvgahX0r.js +1 -0
  33. package/dist/assets/useToast-yRSO1dkm.js +1 -0
  34. package/dist/assets/vendor-charts-RkGK5ROP.js +36 -0
  35. package/dist/assets/vendor-db-l0sNRNKZ.js +1 -0
  36. package/dist/assets/vendor-react-BVZ_anCF.js +4 -0
  37. package/dist/assets/vendor-search-Dw8P0qyA.js +1 -0
  38. package/dist/assets/vendor-ui-BU7NfluV.js +53 -0
  39. package/dist/electron/PowerAutomateApiService-LfW09ZGr.js +147 -0
  40. package/dist/electron/main-CXkNtyv-.js +19789 -0
  41. package/dist/electron/main.js +5 -0
  42. package/dist/electron/preload.js +1 -0
  43. package/dist/icon.png +0 -0
  44. package/dist/index.html +27 -0
  45. package/docs/CODEBASE_ANALYSIS_REPORT.md +309 -0
  46. package/docs/DEBUG_LOGGING_GUIDE.md +244 -0
  47. package/docs/README.md +115 -0
  48. package/docs/TOC_WIRING_GUIDE.md +344 -0
  49. package/docs/analysis/Bullet_Symbol_Bug_Analysis.md +136 -0
  50. package/docs/analysis/DOCXMLATER_ANALYSIS_SUMMARY.txt +169 -0
  51. package/docs/analysis/Document_Processing_Issues_Analysis.md +704 -0
  52. package/docs/analysis/FIELD_PRESERVATION_ANALYSIS.md +1200 -0
  53. package/docs/analysis/INDENTATION_PRESERVE_ANALYSIS.md +181 -0
  54. package/docs/analysis/INDENTATION_PRESERVE_IMPLEMENTATION.md +207 -0
  55. package/docs/analysis/List_Implementation.md +206 -0
  56. package/docs/analysis/List_Implementation_Accuracy_Report.md +366 -0
  57. package/docs/analysis/PROCESSING_OPTIONS_UI_UPDATES.md +220 -0
  58. package/docs/analysis/RefactorStyles.md +852 -0
  59. package/docs/analysis/STYLE_PARAMETER_ENHANCEMENT.md +143 -0
  60. package/docs/analysis/docxmlater-comparison-todo-2025-11-13.md +636 -0
  61. package/docs/analysis/docxmlater-implementation-analysis-2025-11-13.md +340 -0
  62. package/docs/analysis/docxmlater-template_ui-integration-analysis.md +263 -0
  63. package/docs/analysis/github-issues-to-create.md +237 -0
  64. package/docs/api/API_README.md +538 -0
  65. package/docs/api/API_REFERENCE.md +751 -0
  66. package/docs/api/TYPE_DEFINITIONS.md +869 -0
  67. package/docs/architecture/FONT_EMBEDDING_GUIDE.md +318 -0
  68. package/docs/architecture/docxmlater-functions-and-structure.md +726 -0
  69. package/docs/docxmlater-readme.md +1341 -0
  70. package/docs/fixes/EXECUTION_LOG_TEST_BASE.md +573 -0
  71. package/docs/fixes/HYPERLINK_TEXT_SANITIZATION.md +253 -0
  72. package/docs/fixes/README.md +37 -0
  73. package/docs/github-issues/issue-1-body.md +125 -0
  74. package/docs/github-issues/issue-10-body.md +850 -0
  75. package/docs/github-issues/issue-2-body.md +200 -0
  76. package/docs/github-issues/issue-3-body.md +270 -0
  77. package/docs/github-issues/issue-4-body.md +169 -0
  78. package/docs/github-issues/issue-5-body.md +173 -0
  79. package/docs/github-issues/issue-6-body.md +158 -0
  80. package/docs/github-issues/issue-7-body.md +171 -0
  81. package/docs/github-issues/issue-8-body.md +407 -0
  82. package/docs/github-issues/issue-9-body.md +515 -0
  83. package/docs/github-issues/issue-tracker.md +274 -0
  84. package/docs/github-issues/predictive-analysis-2025-10-18.md +2131 -0
  85. package/docs/implementation/List_Framework_Refactor_Plan.md +336 -0
  86. package/docs/implementation/PRIMARY_TEXT_COLOR_FEATURE.md +217 -0
  87. package/docs/implementation/RELEASE_PLAN_v2.1.0.md +362 -0
  88. package/docs/implementation/RefactorStyles.md +588 -0
  89. package/docs/implementation/implement-plan.md +489 -0
  90. package/docs/implementation/missing-helpers-implementation.md +391 -0
  91. package/docs/implementation/refactor-plan.md +520 -0
  92. package/docs/implementation/session-implementation-complete.md +233 -0
  93. package/docs/implementation/session-management-plan.md +250 -0
  94. package/docs/setup-checklist.md +77 -0
  95. package/docs/versions/changelog.md +345 -0
  96. package/electron/customUpdater.ts +656 -0
  97. package/electron/main.ts +2441 -0
  98. package/electron/memoryConfig.ts +187 -0
  99. package/electron/preload.ts +394 -0
  100. package/electron/proxyConfig.ts +340 -0
  101. package/electron/services/BackupService.ts +452 -0
  102. package/electron/services/DictionaryService.ts +402 -0
  103. package/electron/services/LocalDictionaryLookupService.ts +147 -0
  104. package/electron/services/PowerAutomateApiService.ts +231 -0
  105. package/electron/services/SharePointSyncService.ts +474 -0
  106. package/electron/windowsCertStore.ts +427 -0
  107. package/electron/zscalerConfig.ts +381 -0
  108. package/eslint.config.js +92 -0
  109. package/jest.config.js +52 -0
  110. package/package.json +214 -0
  111. package/postcss.config.mjs +6 -0
  112. package/public/icon.png +0 -0
  113. package/publish-release.ps1 +5 -0
  114. package/renovate.json +30 -0
  115. package/src/App.tsx +216 -0
  116. package/src/__mocks__/p-limit.js +12 -0
  117. package/src/__mocks__/styleMock.js +1 -0
  118. package/src/components/common/BugReportButton.tsx +44 -0
  119. package/src/components/common/BugReportDialog.tsx +193 -0
  120. package/src/components/common/Button.tsx +153 -0
  121. package/src/components/common/Card.tsx +86 -0
  122. package/src/components/common/ColorPickerDialog.tsx +177 -0
  123. package/src/components/common/ConfirmDialog.tsx +96 -0
  124. package/src/components/common/DebugConsole.tsx +275 -0
  125. package/src/components/common/EmptyState.tsx +183 -0
  126. package/src/components/common/ErrorBoundary.tsx +98 -0
  127. package/src/components/common/ErrorDetailsDialog.tsx +153 -0
  128. package/src/components/common/ErrorFallback.tsx +218 -0
  129. package/src/components/common/Input.tsx +109 -0
  130. package/src/components/common/Skeleton.tsx +184 -0
  131. package/src/components/common/SplashScreen.tsx +81 -0
  132. package/src/components/common/Toast.tsx +155 -0
  133. package/src/components/common/Tooltip.tsx +79 -0
  134. package/src/components/common/UpdateNotification.tsx +320 -0
  135. package/src/components/comparison/ComparisonWindow.tsx +374 -0
  136. package/src/components/comparison/SideBySideDiff.tsx +486 -0
  137. package/src/components/comparison/index.ts +8 -0
  138. package/src/components/document/DocumentUploader.tsx +288 -0
  139. package/src/components/document/HyperlinkPreview.tsx +430 -0
  140. package/src/components/document/HyperlinkService.md +1484 -0
  141. package/src/components/document/Hyperlink_Technical_Documentation.md +496 -0
  142. package/src/components/document/InlineChangesView.tsx +707 -0
  143. package/src/components/document/ProcessingProgress.tsx +303 -0
  144. package/src/components/document/ProcessingResults.tsx +256 -0
  145. package/src/components/document/TrackedChangesDetail.tsx +530 -0
  146. package/src/components/document/TrackedChangesPanel.tsx +546 -0
  147. package/src/components/document/VirtualDocumentList.tsx +240 -0
  148. package/src/components/editor/DocumentEditor.tsx +723 -0
  149. package/src/components/editor/DocumentEditorModal.tsx +640 -0
  150. package/src/components/editor/EditorQuickActions.tsx +502 -0
  151. package/src/components/editor/EditorToolbar.tsx +312 -0
  152. package/src/components/editor/TableEditor.tsx +926 -0
  153. package/src/components/editor/index.ts +18 -0
  154. package/src/components/layout/Header.tsx +190 -0
  155. package/src/components/layout/Sidebar.tsx +313 -0
  156. package/src/components/layout/TitleBar.tsx +190 -0
  157. package/src/components/navigation/CommandPalette.tsx +233 -0
  158. package/src/components/navigation/KeyboardShortcutsModal.tsx +173 -0
  159. package/src/components/sessions/ChangeItem.tsx +408 -0
  160. package/src/components/sessions/ChangeViewer.tsx +1155 -0
  161. package/src/components/sessions/DocumentComparisonModal.tsx +314 -0
  162. package/src/components/sessions/ProcessingOptions.tsx +297 -0
  163. package/src/components/sessions/ReplacementsTab.tsx +438 -0
  164. package/src/components/sessions/RevisionHandlingOptions.tsx +87 -0
  165. package/src/components/sessions/SessionManager.tsx +188 -0
  166. package/src/components/sessions/StylesEditor.tsx +1335 -0
  167. package/src/components/sessions/TabContainer.tsx +151 -0
  168. package/src/components/sessions/VirtualSessionList.tsx +157 -0
  169. package/src/components/sessions/sessionToProcessorManager.tsx +420 -0
  170. package/src/components/settings/CertificateManager.tsx +410 -0
  171. package/src/components/settings/SegmentedControl.tsx +88 -0
  172. package/src/components/settings/SettingRow.tsx +52 -0
  173. package/src/contexts/GlobalStatsContext.tsx +396 -0
  174. package/src/contexts/SessionContext.tsx +2129 -0
  175. package/src/contexts/ThemeContext.tsx +428 -0
  176. package/src/contexts/UserSettingsContext.tsx +290 -0
  177. package/src/contexts/__tests__/GlobalStatsContext.test.tsx +390 -0
  178. package/src/global.d.ts +273 -0
  179. package/src/hooks/useDocumentQueue.tsx +210 -0
  180. package/src/hooks/useToast.tsx +55 -0
  181. package/src/main.tsx +10 -0
  182. package/src/pages/Analytics.tsx +386 -0
  183. package/src/pages/CurrentSession.tsx +1174 -0
  184. package/src/pages/Dashboard.tsx +319 -0
  185. package/src/pages/Documents.tsx +317 -0
  186. package/src/pages/Projects.tsx +250 -0
  187. package/src/pages/Reporting.tsx +386 -0
  188. package/src/pages/Search.tsx +349 -0
  189. package/src/pages/Sessions.tsx +285 -0
  190. package/src/pages/Settings.tsx +2662 -0
  191. package/src/services/HyperlinkService.ts +1085 -0
  192. package/src/services/document/DocXMLaterProcessor.ts +617 -0
  193. package/src/services/document/DocumentProcessingComparison.ts +856 -0
  194. package/src/services/document/DocumentSnapshotService.ts +575 -0
  195. package/src/services/document/WordDocumentProcessor.ts +10509 -0
  196. package/src/services/document/__tests__/DocXMLaterProcessor.hyperlinks.test.md +311 -0
  197. package/src/services/document/__tests__/WordDocumentProcessor.integration.test.ts +515 -0
  198. package/src/services/document/__tests__/WordDocumentProcessor.test.ts +812 -0
  199. package/src/services/document/blanklines/BlankLineManager.ts +658 -0
  200. package/src/services/document/blanklines/__tests__/paragraphChecks.test.ts +281 -0
  201. package/src/services/document/blanklines/helpers/blankLineInsertion.ts +87 -0
  202. package/src/services/document/blanklines/helpers/blankLineSnapshot.ts +251 -0
  203. package/src/services/document/blanklines/helpers/clearCustom.ts +121 -0
  204. package/src/services/document/blanklines/helpers/contextChecks.ts +117 -0
  205. package/src/services/document/blanklines/helpers/imageChecks.ts +51 -0
  206. package/src/services/document/blanklines/helpers/paragraphChecks.ts +236 -0
  207. package/src/services/document/blanklines/helpers/removeBlanksBetweenListItems.ts +91 -0
  208. package/src/services/document/blanklines/helpers/removeTrailingBlanks.ts +35 -0
  209. package/src/services/document/blanklines/helpers/tableGuards.ts +21 -0
  210. package/src/services/document/blanklines/index.ts +67 -0
  211. package/src/services/document/blanklines/rules/additionRules.ts +337 -0
  212. package/src/services/document/blanklines/rules/indentationRules.ts +317 -0
  213. package/src/services/document/blanklines/rules/removalRules.ts +362 -0
  214. package/src/services/document/blanklines/rules/ruleTypes.ts +92 -0
  215. package/src/services/document/blanklines/types.ts +29 -0
  216. package/src/services/document/helpers/ImageBorderCropper.ts +377 -0
  217. package/src/services/document/helpers/__tests__/whitespace.test.ts +272 -0
  218. package/src/services/document/helpers/whitespace.ts +117 -0
  219. package/src/services/document/list/ListNormalizer.ts +947 -0
  220. package/src/services/document/list/index.ts +45 -0
  221. package/src/services/document/list/list-detection.ts +275 -0
  222. package/src/services/document/list/list-types.ts +162 -0
  223. package/src/services/document/processors/HyperlinkProcessor.ts +370 -0
  224. package/src/services/document/processors/ListProcessor.ts +257 -0
  225. package/src/services/document/processors/StructureProcessor.ts +176 -0
  226. package/src/services/document/processors/StyleProcessor.ts +389 -0
  227. package/src/services/document/processors/TableProcessor.ts +2238 -0
  228. package/src/services/document/processors/__tests__/HyperlinkProcessor.test.ts +314 -0
  229. package/src/services/document/processors/__tests__/ListProcessor.test.ts +291 -0
  230. package/src/services/document/processors/__tests__/StructureProcessor.test.ts +257 -0
  231. package/src/services/document/processors/__tests__/TableProcessor.hlp-tips-bullets.test.ts +459 -0
  232. package/src/services/document/processors/__tests__/TableProcessor.test.ts +1604 -0
  233. package/src/services/document/processors/index.ts +28 -0
  234. package/src/services/document/types/docx-processing.ts +310 -0
  235. package/src/services/editor/EditorActionHandlers.ts +901 -0
  236. package/src/services/editor/index.ts +13 -0
  237. package/src/setupTests.ts +47 -0
  238. package/src/styles/global.css +782 -0
  239. package/src/types/backup.ts +132 -0
  240. package/src/types/dictionary.ts +125 -0
  241. package/src/types/document-processing.ts +331 -0
  242. package/src/types/docxmlater-augments.d.ts +142 -0
  243. package/src/types/editor.ts +280 -0
  244. package/src/types/electron.ts +340 -0
  245. package/src/types/globalStats.ts +155 -0
  246. package/src/types/hyperlink.ts +471 -0
  247. package/src/types/operations.ts +354 -0
  248. package/src/types/session.ts +427 -0
  249. package/src/types/settings.ts +112 -0
  250. package/src/utils/MemoryMonitor.ts +248 -0
  251. package/src/utils/cn.ts +6 -0
  252. package/src/utils/colorConvert.ts +306 -0
  253. package/src/utils/diffUtils.ts +347 -0
  254. package/src/utils/documentUtils.ts +202 -0
  255. package/src/utils/electronGuard.ts +62 -0
  256. package/src/utils/indexedDB.ts +915 -0
  257. package/src/utils/logger.ts +717 -0
  258. package/src/utils/pathSecurity.ts +232 -0
  259. package/src/utils/pathValidator.ts +236 -0
  260. package/src/utils/processingTimeEstimator.ts +153 -0
  261. package/src/utils/safeJsonParse.ts +62 -0
  262. package/src/utils/textSanitizer.ts +162 -0
  263. package/src/utils/urlHelpers.ts +304 -0
  264. package/src/utils/urlPatterns.ts +198 -0
  265. package/src/utils/urlSanitizer.ts +152 -0
  266. package/src/vite-env.d.ts +11 -0
  267. package/tsconfig.electron.json +19 -0
  268. package/tsconfig.json +36 -0
  269. package/tsconfig.node.json +12 -0
  270. package/typedoc.json +45 -0
  271. package/vite.config.ts +152 -0
@@ -0,0 +1,340 @@
1
+ import { app, session } from 'electron';
2
+ import * as os from 'os';
3
+ import { zscalerConfig } from './zscalerConfig';
4
+ import { logger } from '../src/utils/logger';
5
+
6
+ const log = logger.namespace('ProxyConfig');
7
+
8
+ /**
9
+ * Proxy configuration and detection for corporate environments
10
+ * Enhanced with session management, connection cleanup, and Zscaler integration
11
+ */
12
+ export class ProxyConfig {
13
+ private proxyUrl: string | null = null;
14
+ private proxyAuth: { username: string; password: string } | null = null;
15
+ private bypassList: string[] = ['localhost', '127.0.0.1', '<local>'];
16
+ private isProxyConfigured: boolean = false;
17
+ private maxRetries: number = 3;
18
+
19
+ constructor() {
20
+ this.detectProxy();
21
+ this.detectLocalProxy();
22
+ }
23
+
24
+ /**
25
+ * Detect localhost proxy servers (WSUS, MSDTC, etc.)
26
+ */
27
+ private detectLocalProxy(): void {
28
+ // Common local proxy ports used by enterprise software
29
+ const localProxyPorts = [
30
+ 8005, // WSUS/MSDTC (as reported by user)
31
+ 8080, // Common proxy port
32
+ 3128, // Squid default
33
+ 8888, // Fiddler/Charles
34
+ 9090, // Another common proxy
35
+ 1080 // SOCKS proxy
36
+ ];
37
+
38
+ // Check if we already have a proxy configured
39
+ if (this.proxyUrl && !this.proxyUrl.includes('localhost') && !this.proxyUrl.includes('127.0.0.1')) {
40
+ log.info('[ZscalerConfig] Non-localhost proxy already configured, skipping localhost detection');
41
+ return;
42
+ }
43
+
44
+ // Check for specific localhost proxies
45
+ for (const port of localProxyPorts) {
46
+ // Check if this might be the active proxy
47
+ if (process.env[`LOCALHOST_PROXY_${port}`] === 'true') {
48
+ const proxyUrl = `http://localhost:${port}`;
49
+ log.info(` Detected localhost proxy on port ${port} from environment`);
50
+
51
+ if (port === 8005) {
52
+ log.info('[ZscalerConfig] ⚠️ WSUS/MSDTC proxy detected on port 8005 - Mutual TLS likely required');
53
+ log.info('[ZscalerConfig] This proxy requires special handling for certificate authentication');
54
+ }
55
+
56
+ // Only set if we don't already have a proxy
57
+ if (!this.proxyUrl) {
58
+ this.proxyUrl = proxyUrl;
59
+ log.info(` Using localhost proxy: ${proxyUrl}`);
60
+ }
61
+ break;
62
+ }
63
+ }
64
+
65
+ // Log if we detect the Windows Update localhost:8005 configuration
66
+ if (!this.proxyUrl) {
67
+ log.info('[ZscalerConfig] Checking for Windows Update proxy configuration...');
68
+ // This is informational - the actual proxy might be transparent
69
+ log.info('[ZscalerConfig] Note: Windows Update may be using localhost:8005 for WSUS');
70
+ log.info('[ZscalerConfig] This often indicates enterprise network with mutual TLS requirements');
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Detect proxy settings from environment variables
76
+ */
77
+ private detectProxy(): void {
78
+ // Check common proxy environment variables
79
+ const proxyEnvVars = [
80
+ 'HTTPS_PROXY',
81
+ 'https_proxy',
82
+ 'HTTP_PROXY',
83
+ 'http_proxy',
84
+ 'ALL_PROXY',
85
+ 'all_proxy'
86
+ ];
87
+
88
+ for (const envVar of proxyEnvVars) {
89
+ const proxyValue = process.env[envVar];
90
+ if (proxyValue) {
91
+ this.proxyUrl = proxyValue;
92
+ log.info(` Detected proxy from ${envVar}: ${this.proxyUrl}`);
93
+ break;
94
+ }
95
+ }
96
+
97
+ // If Zscaler is detected but no proxy is set, use a default Zscaler proxy
98
+ if (!this.proxyUrl && zscalerConfig.isDetected()) {
99
+ log.info('[ZscalerConfig] Zscaler detected but no proxy configured');
100
+ // Zscaler typically uses transparent proxy, so we might not need explicit proxy settings
101
+ // But we should ensure certificate handling is properly configured
102
+ log.info('[ZscalerConfig] Relying on Zscaler transparent proxy');
103
+ }
104
+
105
+ // Check for NO_PROXY bypass list
106
+ const noProxy = process.env.NO_PROXY || process.env.no_proxy;
107
+ if (noProxy) {
108
+ this.bypassList = [...this.bypassList, ...noProxy.split(',').map(s => s.trim())];
109
+ log.info(` Proxy bypass list: ${this.bypassList.join(', ')}`);
110
+ }
111
+
112
+ // Check for proxy authentication
113
+ const proxyUsername = process.env.PROXY_USERNAME || process.env.proxy_username;
114
+ const proxyPassword = process.env.PROXY_PASSWORD || process.env.proxy_password;
115
+
116
+ if (proxyUsername && proxyPassword) {
117
+ this.proxyAuth = { username: proxyUsername, password: proxyPassword };
118
+ log.info('[ZscalerConfig] Proxy authentication configured (credentials masked)');
119
+ }
120
+
121
+ // Log corporate CA certificate configuration
122
+ const caCert = process.env.NODE_EXTRA_CA_CERTS;
123
+ if (caCert) {
124
+ log.info(` Corporate CA certificate configured: ${caCert}`);
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Configure Electron app with proxy settings
130
+ */
131
+ public configureApp(): void {
132
+ if (!this.proxyUrl) {
133
+ log.info('[ZscalerConfig] No proxy detected, using direct connection');
134
+ return;
135
+ }
136
+
137
+ // Set proxy for Electron
138
+ log.info(`[ProxyConfig] Configuring app with proxy: ${this.proxyUrl}`);
139
+
140
+ // Configure command line switches for Chromium
141
+ app.commandLine.appendSwitch('proxy-server', this.proxyUrl);
142
+
143
+ if (this.bypassList.length > 0) {
144
+ app.commandLine.appendSwitch('proxy-bypass-list', this.bypassList.join(','));
145
+ }
146
+
147
+ // Configure proxy authentication handler at app level
148
+ if (this.proxyAuth) {
149
+ app.on('login', (event, webContents, request, authInfo, callback) => {
150
+ if (authInfo.isProxy && this.proxyAuth) {
151
+ event.preventDefault();
152
+ log.info('[ZscalerConfig] Providing proxy authentication for:', authInfo.host);
153
+ callback(this.proxyAuth.username, this.proxyAuth.password);
154
+ }
155
+ });
156
+ }
157
+ }
158
+
159
+ /**
160
+ * Configure session-level proxy with connection cleanup
161
+ * This is crucial for preventing ECONNRESET errors
162
+ */
163
+ public async configureSessionProxy(ses?: Electron.Session): Promise<void> {
164
+ const targetSession = ses || session.defaultSession;
165
+
166
+ try {
167
+ // CRITICAL: Close all existing connections to prevent connection pool reuse
168
+ log.info('[ZscalerConfig] Closing all existing connections...');
169
+ log.info('[ZscalerConfig] Session info:', {
170
+ cacheSize: await targetSession.getCacheSize(),
171
+ userAgent: targetSession.getUserAgent().substring(0, 100),
172
+ protocol: targetSession.protocol
173
+ });
174
+ await targetSession.closeAllConnections();
175
+
176
+ if (!this.proxyUrl) {
177
+ log.info('[ZscalerConfig] No proxy detected, configuring direct connection');
178
+ await targetSession.setProxy({ mode: 'direct' });
179
+ this.isProxyConfigured = true;
180
+ return;
181
+ }
182
+
183
+ log.info('[ZscalerConfig] Configuring session proxy:', this.proxyUrl);
184
+
185
+ // Build proxy configuration
186
+ const proxyConfig: Electron.ProxyConfig = {
187
+ proxyRules: this.proxyUrl,
188
+ proxyBypassRules: this.bypassList.join(',')
189
+ };
190
+
191
+ // Check for PAC script
192
+ const pacUrl = process.env.PAC_URL || process.env.pac_url;
193
+ if (pacUrl) {
194
+ log.info('[ZscalerConfig] Using PAC script:', pacUrl);
195
+ proxyConfig.pacScript = pacUrl;
196
+ proxyConfig.mode = 'pac_script';
197
+ }
198
+
199
+ // Apply proxy configuration
200
+ await targetSession.setProxy(proxyConfig);
201
+
202
+ // Force reload proxy configuration
203
+ await targetSession.forceReloadProxyConfig();
204
+
205
+ log.info('[ZscalerConfig] Session proxy configured successfully');
206
+ this.isProxyConfigured = true;
207
+
208
+ } catch (error) {
209
+ log.error('[ZscalerConfig] Failed to configure session proxy:', error);
210
+ throw error;
211
+ }
212
+ }
213
+
214
+ /**
215
+ * Reset proxy configuration with retry logic
216
+ */
217
+ public async resetProxyWithRetry(ses?: Electron.Session, retryCount: number = 0): Promise<void> {
218
+ const targetSession = ses || session.defaultSession;
219
+
220
+ try {
221
+ log.info(` Resetting proxy configuration (attempt ${retryCount + 1}/${this.maxRetries})`);
222
+
223
+ // Close all connections
224
+ await targetSession.closeAllConnections();
225
+
226
+ // Wait a bit for connections to fully close
227
+ await new Promise(resolve => setTimeout(resolve, 500));
228
+
229
+ // Reconfigure proxy
230
+ await this.configureSessionProxy(targetSession);
231
+
232
+ } catch (error) {
233
+ if (retryCount < this.maxRetries - 1) {
234
+ log.info('[ZscalerConfig] Retrying proxy reset...');
235
+ await new Promise(resolve => setTimeout(resolve, 1000 * (retryCount + 1)));
236
+ return this.resetProxyWithRetry(targetSession, retryCount + 1);
237
+ }
238
+ throw error;
239
+ }
240
+ }
241
+
242
+ /**
243
+ * Get User-Agent without Electron identifier
244
+ * Some corporate proxies reject requests with "Electron" in User-Agent
245
+ */
246
+ public getCleanUserAgent(): string {
247
+ const currentUA = session.defaultSession.getUserAgent();
248
+ // Remove Electron/ and Electron-specific identifiers
249
+ const cleanUA = currentUA
250
+ .split(' ')
251
+ .filter(part => !part.includes('Electron'))
252
+ .join(' ')
253
+ .replace(/\s+/g, ' ')
254
+ .trim();
255
+
256
+ log.info('[ZscalerConfig] Clean User-Agent:', cleanUA);
257
+ return cleanUA;
258
+ }
259
+
260
+ /**
261
+ * Get proxy configuration for net.request
262
+ */
263
+ public getProxyConfig(): { proxyRules?: string; pacScript?: string } | null {
264
+ if (!this.proxyUrl) {
265
+ return null;
266
+ }
267
+
268
+ return {
269
+ proxyRules: this.proxyUrl,
270
+ // pacScript can be added if PAC file URL is provided via environment variable
271
+ };
272
+ }
273
+
274
+ /**
275
+ * Check if URL should bypass proxy
276
+ */
277
+ public shouldBypassProxy(url: string): boolean {
278
+ try {
279
+ const urlObj = new URL(url);
280
+ const hostname = urlObj.hostname;
281
+
282
+ // Check if hostname is in bypass list
283
+ for (const bypass of this.bypassList) {
284
+ if (bypass === '<local>' && !hostname.includes('.')) {
285
+ return true;
286
+ }
287
+ if (hostname === bypass || hostname.endsWith(`.${bypass}`)) {
288
+ return true;
289
+ }
290
+ }
291
+ } catch (error) {
292
+ log.error('[ZscalerConfig] Error checking bypass:', error);
293
+ }
294
+
295
+ return false;
296
+ }
297
+
298
+ /**
299
+ * Get proxy URL
300
+ */
301
+ public getProxyUrl(): string | null {
302
+ return this.proxyUrl;
303
+ }
304
+
305
+ /**
306
+ * Get proxy authentication credentials
307
+ */
308
+ public getProxyAuth(): { username: string; password: string } | null {
309
+ return this.proxyAuth;
310
+ }
311
+
312
+ /**
313
+ * Check if proxy is configured
314
+ */
315
+ public isConfigured(): boolean {
316
+ return this.isProxyConfigured;
317
+ }
318
+
319
+ /**
320
+ * Log proxy configuration for debugging
321
+ */
322
+ public logConfiguration(): void {
323
+ log.info('[ZscalerConfig] Configuration Summary:');
324
+ log.info(` - Proxy URL: ${this.proxyUrl || 'Not configured (direct connection)'}`);
325
+ log.info(` - Proxy Auth: ${this.proxyAuth ? 'Configured' : 'Not configured'}`);
326
+ log.info(` - Bypass List: ${this.bypassList.join(', ')}`);
327
+ log.info(` - Zscaler Status: ${zscalerConfig.isDetected() ? 'DETECTED' : 'Not detected'}`);
328
+ log.info(` - NODE_EXTRA_CA_CERTS: ${process.env.NODE_EXTRA_CA_CERTS || 'Not configured'}`);
329
+ log.info(` - NODE_TLS_REJECT_UNAUTHORIZED: ${process.env.NODE_TLS_REJECT_UNAUTHORIZED || 'Default (1)'}`);
330
+ log.info(` - ZSCALER_BYPASS: ${process.env.ZSCALER_BYPASS || 'Not set'}`);
331
+ log.info(` - Platform: ${os.platform()}`);
332
+ log.info(` - Node Version: ${process.version}`);
333
+ log.info(` - Electron Version: ${process.versions.electron}`);
334
+ log.info(` - App Version: ${app.getVersion()}`);
335
+ log.info(` - System Locale: ${app.getLocale()}`);
336
+ }
337
+ }
338
+
339
+ // Export singleton instance
340
+ export const proxyConfig = new ProxyConfig();