feat(IDE-1652): migrate HTML settings page onto FolderConfigSettings + ExecuteCommandBridge (3/3)#396
Conversation
…and ExecuteCommandBridge (3/3) - HTMLSettingsPreferencePage: rewired to read/write settings via FolderConfigSettings and LsSettingsRegistry instead of the legacy Settings / IdeConfigData path; bridges auth and settings updates through ExecuteCommandBridge - settings-fallback.html: sync from snyk-ls shared_ide_resources with updated JS wiring for new settings bridge commands - HTMLSettingsPreferencePageTest: updated to cover new wiring After this PR all legacy POJOs (Settings, FolderConfig, FolderConfigs, FolderConfigsParam, IdeConfigData) and native UI shells (NativeProjectPropertyPage, PreferencesPage, TokenFieldEditor) are dead code with no callers. PR #393 deletes them.
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
This comment has been minimized.
This comment has been minimized.
…cture Deletes all code made dead by the new LsSettingsRegistry / FolderConfigSettings / LspConfigurationParam architecture landed in PRs #394, #395, #396: Native settings UI (no callers after HTML-only migration): - PreferencesPage, TokenFieldEditor, NativeProjectPropertyPage - SnykPreferencePageFactoryTest, ProjectPropertyPageFactoryTest Legacy LS protocol POJOs (replaced by LspConfigurationParam / ConfigSetting / LspFolderConfig / FolderConfigSettings): - Settings, FolderConfig, FolderConfigsParam, FolderConfigs, IdeConfigData - FolderConfigTest
| prefs.markExplicitlyChangedNoFlush(entry.prefKey); | ||
| } else { | ||
| prefs.store(entry.prefKey, nodeToString(n)); | ||
| prefs.markExplicitlyChangedNoFlush(entry.prefKey); |
There was a problem hiding this comment.
Won't fix in this PR. The fallback HTML is owned by snyk-ls/shared_ide_resources/ — the fix (send only diff, not all fields) belongs there. Tracked in IDE-2072.
| var fields = folderNode.fields(); | ||
| while (fields.hasNext()) { | ||
| var field = fields.next(); | ||
| String key = field.getKey(); |
There was a problem hiding this comment.
Won't fix here — if the LS changes the folder key contract (e.g. folderPath → folder_path), the plugin will need updating regardless. Eclipse has no LS integration tests currently, so the failure mode is a silent regression caught only by manual testing. Raising a separate ticket to add LS integration test coverage is the right long-term fix.
| cli_path: get('cli_path').value, | ||
| automatic_download: get('automatic_download').checked, | ||
| binary_base_url: get('binary_base_url').value || get('binary_base_url').placeholder, | ||
| cli_release_channel: get('cli_release_channel').value === 'custom' ? (function() { var v = (get('cli_release_channel_custom').value || '').trim(); if (v && v.charAt(0) !== 'v') { v = 'v' + v; } return v || 'stable'; })() : get('cli_release_channel').value, |
There was a problem hiding this comment.
settings-fallback.html is owned by snyk-ls/shared_ide_resources/. This behavior is the LS's concern.
| <option value="preview" {{CHANNEL_PREVIEW_SELECTED}}>Preview</option> | ||
| <option value="custom" {{CHANNEL_CUSTOM_SELECTED}}>Specify version…</option> | ||
| </select> | ||
| <input type="text" id="cli_release_channel_custom" name="cli_release_channel_custom" class="{{CLI_RELEASE_CHANNEL_CUSTOM_HIDDEN}}" placeholder="e.g. v1.1292.0" value="{{CLI_RELEASE_CHANNEL_CUSTOM_VALUE}}" maxlength="20" pattern="^v?(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$"> |
There was a problem hiding this comment.
Won't fix here — settings-fallback.html is synced from snyk-ls/shared_ide_resources/. The placeholder substitution ({{CHANNEL_CUSTOM_SELECTED}} etc.) belongs in the LS repo. Eclipse ships the file as-is.
| continue; | ||
| } | ||
| if (LsFolderSettingsKeys.SCAN_COMMAND_CONFIG.equals(key)) { | ||
| Map<String, ScanCommandConfig> scanCommandMap = objectMapper.convertValue( |
There was a problem hiding this comment.
Fixed — added isObject() guard before convertValue and wrapped in try/catch IllegalArgumentException to isolate malformed scan_command_config to the single folder without aborting the rest of the save.
| <label for="cliPath"><span data-toggle="tooltip">CLI Path<span class="tooltip-popup">Path to Snyk CLI executable</span></span></label> | ||
| <input type="text" id="cliPath" name="cliPath" value="{{CLI_PATH}}" placeholder="/path/to/snyk-cli"> | ||
| <label for="cli_path"><span data-toggle="tooltip">CLI Path<span class="tooltip-popup">Path to Snyk CLI executable</span></span></label> | ||
| <input type="text" id="cli_path" name="cli_path" value="{{CLI_PATH}}" placeholder="/path/to/snyk-cli"> |
There was a problem hiding this comment.
Fixed — added htmlAttr() helper that escapes &, ", < and applied it to {{CLI_PATH}} and {{CLI_BASE_DOWNLOAD_URL}} substitutions in loadFallbackHtml().
| } | ||
| } | ||
|
|
||
| function validateCliVersion() { |
There was a problem hiding this comment.
Won't fix here — settings-fallback.html is owned by snyk-ls/shared_ide_resources/. JS validation logic belongs there.
|
🟠 High — Posted as a PR-level comment because the affected file ( [plugin/src/main/java/io/snyk/eclipse/plugin/preferences/IdeConfigData.java] PR description states "After this lands, all legacy POJOs are dead code with no callers — PR #393 deletes them." Verified locally: after this diff is applied, Leaving the POJO in the tree (with its Fix: Prefer to delete If you must defer to PR #393, add a top-of-file marker so the next reader understands the state: // @deprecated Slated for deletion in PR #393. No remaining callers after PR #396
// (HTMLSettingsPreferencePage migrated to JsonNode-driven parsing).
// Do not add new fields.— AI review comment |
Converting to non-blocking review — findings remain visible inline and in the review body, but should not block merge.
…cture Deletes all code made dead by the new LsSettingsRegistry / FolderConfigSettings / LspConfigurationParam architecture landed in PRs #394, #395, #396: Native settings UI (no callers after HTML-only migration): - PreferencesPage, TokenFieldEditor, NativeProjectPropertyPage - SnykPreferencePageFactoryTest, ProjectPropertyPageFactoryTest Legacy LS protocol POJOs (replaced by LspConfigurationParam / ConfigSetting / LspFolderConfig / FolderConfigSettings): - Settings, FolderConfig, FolderConfigsParam, FolderConfigs, IdeConfigData - FolderConfigTest
This comment has been minimized.
This comment has been minimized.
…ception Non-object nodes and null boolean fields throw IllegalArgumentException which the outer JsonProcessingException catch misses, silently aborting the whole save. Guard with isObject() check and isolate the failure to the single folder.
Pref values substituted into HTML value= attributes with no escaping — a stored value containing "><script> would render in the privileged SWT Browser. Added htmlAttr() helper (escapes & , ", <) and applied to CLI_PATH and CLI_BASE_DOWNLOAD_URL substitutions.
|
Re: #396 (comment) Already deleted in the follow-up PR #393 — no action needed here. |
PR Reviewer Guide 🔍
|
acke
left a comment
There was a problem hiding this comment.
Re-review (review-orchestrator)
Verdict: APPROVE
Verification of prior comments
| # | File:Line | Status |
|---|---|---|
| 1 | HTMLSettingsPreferencePage.java:198 fallback HTML diff-only save |
⏸️ Declined — owned by snyk-ls/shared_ide_resources/ (IDE-2072) |
| 2 | HTMLSettingsPreferencePage.java:244 LS folder-key test gap |
⏸️ Declined — separate ticket |
| 3 | settings-fallback.html:376 fallback UX |
⏸️ Declined — owned upstream |
| 4 | settings-fallback.html:345 placeholder |
⏸️ Declined — owned upstream |
| 5 | HTMLSettingsPreferencePage.java:250 scan_command_config |
✅ Fixed (ac6e1ef) — isObject() guard + try/catch |
| 6 | HTMLSettingsPreferencePage.java:159-160 XSS in loadFallbackHtml |
✅ Fixed (9df85ea) — htmlAttr() helper. See M1 — escape set incomplete |
| 7 | settings-fallback.html:461 JS validation |
⏸️ Declined — owned upstream |
| 8 | PR-level: IdeConfigData.java orphan |
⏸️ Deferred to #393 — verified deleted there ✓ |
New pass findings (4)
- 🟡 Medium
HTMLSettingsPreferencePage.java:278-281—htmlAttrescapes&/"/<only; safe for double-quoted attribute context but brittle if reused - 🟡 Medium
HTMLSettingsPreferencePage.java:312-326—performOkraces betweenbrowser.evaluateandrunAsync(updateConfiguration)if the JS save handler is async - 🔵 Low
HTMLSettingsPreferencePage.java:270-272—processFolderConfigsilently flattens unknown folder field types to text - 🔵 Low
HTMLSettingsPreferencePage.java:155-169—loadFallbackHtmlre-reads the template per page load (trivial cost)
Important cross-PR note: this PR's outbound flow goes through the form parser (not persistGlobalSettings), so the allowlist concern raised on #395 does NOT affect it.
See inline comments for full block-formatted findings.
Manifest: .claude/reviews/396/TOOLS_USED.md
— AI review comment
| private static String htmlAttr(String v) { | ||
| if (v == null) return ""; | ||
| return v.replace("&", "&").replace("\"", """).replace("<", "<"); | ||
| } |
There was a problem hiding this comment.
🟡 Medium
[HTMLSettingsPreferencePage.java:278-281] htmlAttr escapes &, ", < but not > or '. For attribute values inside double-quoted HTML this is technically sufficient, but it's a brittle invariant — if a future template uses single-quoted attributes or embeds the value in textContent/URL/JS context, the helper underescapes.
Fix:
Either inline-document the constraint:
/** Escapes for double-quoted HTML attribute context only. Do not use in JS/URL contexts. */
private static String htmlAttr(String v) { ... }Or switch to org.apache.commons.text.StringEscapeUtils.escapeHtml4(v) and rename to htmlEscape.
— AI review comment
| } else if (node.isBoolean()) { | ||
| config = config.withSetting(key, node.booleanValue(), true); | ||
| } else { | ||
| config = config.withSetting(key, node.asText(), true); |
There was a problem hiding this comment.
🔵 Low
[HTMLSettingsPreferencePage.java:270-272] processFolderConfig stores unknown folder field types as raw text. If a future LS adds a structured folder field and the registry hasn't been updated, the value gets flattened to a JSON string. Symptom would be confusing downstream type errors rather than a clear "unknown key" log.
Fix:
Add an else warn log:
} else {
SnykLogger.logInfo("processFolderConfig: storing unknown field type as text for key=" + key
+ " jsonType=" + node.getNodeType());
config = config.withSetting(key, node.asText(), true);
}— AI review comment
| prefs.getPref(Preferences.CLI_BASE_URL, "https://downloads.snyk.io")) | ||
| .replace("{{CLI_PATH}}", prefs.getCliPath()) | ||
| htmlAttr(prefs.getPref(Preferences.CLI_BASE_URL, "https://downloads.snyk.io"))) | ||
| .replace("{{CLI_PATH}}", htmlAttr(prefs.getCliPath())) |
There was a problem hiding this comment.
🔵 Low
[HTMLSettingsPreferencePage.java:155-169] loadFallbackHtml reads the template once per page load. If the user opens settings repeatedly during a session, getResourceAsStream reopens the jar each time and re-substitutes. Trivial cost, but caching the template + lazy-substituting the dynamic placeholders would mirror typical Eclipse patterns. Skip if you've measured no perf concern.
— AI review comment
|
🟡 Medium [HTMLSettingsPreferencePage.java:312-326] (Posted as PR-level comment because target line is outside this PR's diff hunks —
The risk is non-obvious because the LS-served HTML lives outside this repo and could change. Fix: — AI review comment |
Summary
Third and final new PR in the
feat/IDE-1652split. Migrates the HTML settings page to the new store introduced in PR #395. After this lands, all legacy POJOs and native UI shells are dead code with no callers — PR #393 deletes them.HTMLSettingsPreferencePage— rewired to read/write settings viaFolderConfigSettingsandLsSettingsRegistryinstead of the legacySettings/IdeConfigDatapath; bridges auth and settings updates throughExecuteCommandBridgesettings-fallback.html— synced fromsnyk-lsshared IDE resources with updated JS wiring for new settings bridge commandsHTMLSettingsPreferencePageTest— updated to cover new wiringDead code after this PR (deleted by PR #393)
Settings,FolderConfig,FolderConfigsParam,FolderConfigs,IdeConfigData,NativeProjectPropertyPage,PreferencesPage,TokenFieldEditor,LsRuntimeEnvironmentenv-var path,Preferencesnative getters.PR sequence
Test plan
./mvnw test -pl plugin,testspasses./mvnw pmd:check -pl plugin— zero violations