feat(IDE-1701): settings page auth flow — bridge persist and forward apiUrl#724
Conversation
…nd bridge Consolidates __ideLogin__ and __ideLogout__ into a single __ideExecuteCommand__ bridge function, and passes auth configuration params to the login command.
✅ 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. |
- Use discriminated union for WebviewMessage (SaveConfigMessage | ExecuteCommandMessage) - Validate arguments as array in isWebviewMessage type guard - Use ErrorHandler.handle in catch block instead of template literal (preserves stack trace) - Remove unreachable default case from switch (unknown types rejected by type guard) - Add missing tests: empty command guard, empty config guard, non-array arguments, error path - Fix ordering assertion to use getCall() instead of indexOf() - Add test for injectIdeScripts with no closing body tag
Wire up window.__ideCallbacks__ registry and commandResult message round-trip so the webview can receive LS command results asynchronously.
…use [IDE-1701] Move the window.__ideExecuteCommand__ client-side script builder and extension-side command dispatch into a standalone ExecuteCommandBridge class. MessageHandlerFactory and HtmlInjectionService delegate to it, enabling any future HTML webview (e.g. tree view) to reuse the same bridge.
Adds a static guard flag on AuthenticationService that is set true while setEndpoint is running. ConfigurationWatcher skips clearToken when the flag is set, preventing the login flow from wiping the token it just received.
… flag - Revert persist flag from updateTokenAndEndpoint — always saves and triggers scan - Revert persist destructuring in hasAuthenticated notification handler - Add setAuthenticationMethod/setInsecure to IConfiguration/Configuration - Add bridge persist in MessageHandlerFactory: when snyk.login called with 3+ args from settings page, save authMethod/endpoint/insecure to IDE storage before forwarding to LS (no didChangeConfiguration for http.proxyStrictSSL; snyk.* changes handled idempotently by LS) - Pass configuration to MessageHandlerFactory in extension.ts - Add tests for login args persist and auth method mapping
Pass apiUrl alongside token when calling window.setAuthToken from the hasAuthenticated notification so the settings page can update both fields.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Resolved conflict in commandController.test.ts by keeping both the initiateLogin tests (from this branch) and the truncateForDisplay tests (from main), and aligning import style to use assert namespace.
- Validate callbackId against /^__cb_\d+$/ in ExecuteCommandBridge before echoing back to JS, preventing prototype-pollution via crafted keys - Guard window.setAuthToken call with typeof check in injected script so pages that have not yet defined setAuthToken do not throw on message receipt
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
…E-1701] The LS HTML settings page handles auth method, endpoint, and insecure persistence itself via auto-save, so the extension no longer needs to snapshot login args before forwarding snyk.login. Remove saveLoginArgs from MessageHandlerFactory and drop the configuration dependency. Remove the authFlowUpdatingEndpoint static guard from AuthenticationService and the conditional clearToken() skip in ConfigurationWatcher — the guard is no longer needed since the extension is not writing the endpoint during the auth flow. Also remove setAuthenticationMethod and setInsecure from IConfiguration as they have no remaining callers.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
6dd2715 to
d9db4ba
Compare
This comment has been minimized.
This comment has been minimized.
|
|
||
| export interface IMessageHandlerFactory { | ||
| handleMessage(message: unknown): Promise<void>; | ||
| handleMessage(message: unknown): Promise<{ callbackId: string; result: unknown } | void>; |
| (msg: unknown) => this.messageHandlerFactory.handleMessage(msg), | ||
| async (msg: unknown) => { | ||
| const callbackResult = await this.messageHandlerFactory.handleMessage(msg); | ||
| if (callbackResult?.callbackId) { |
There was a problem hiding this comment.
when do we have a callbackId ? and what does it mean ?
There was a problem hiding this comment.
added code comment
This comment has been minimized.
This comment has been minimized.
Prevents XSS-to-arbitrary-command escalation by rejecting any command not prefixed with "snyk." before it reaches vscode.commands.executeCommand.
PR Reviewer Guide 🔍
|
What & Why
The settings page drives authentication via
snyk.loginwith[authMethod, endpoint, insecure]args. Before forwarding to the LS, the IDE must persist these values locally so they survive a page close. Additionally,$/snyk.hasAuthenticatednow carriesapiUrlwhich is forwarded to the webview so the settings page can update both fields after auth.Changes
ExecuteCommandBridge(new shared class)Replaces
__ideLogin__/__ideLogout__JS bridge functions with a singlewindow.__ideExecuteCommand__(cmd, args, callback)bridge. Callback results returned to JS viawindow.__ideCallbacks__.MessageHandlerFactory— bridge persistWhen
type === 'executeCommand',command === 'snyk.login', andargs.length >= 3, saves auth params to VS Code settings before forwarding toExecuteCommandBridge:args[0]mapped to VS Code auth method string ("oauth"→'OAuth2 (Recommended)',"pat"→'Personal Access Token',"token"→'API Token (Legacy)') and written via newIConfiguration.setAuthenticationMethod()args[1](endpoint) written viaconfiguration.setEndpoint()wrapped in theAuthenticationService.authFlowUpdatingEndpointguard — preventsConfigurationWatcherfrom clearing the token when the endpoint changesargs[2](insecure) written via newIConfiguration.setInsecure()→ stores!insecuretohttp.proxyStrictSSLIConfigurationreceivesIConfigurationas an optional 4th constructor param;extension.tspasses itSyncConfigurationFeaturefires a redundantdidChangeConfigurationforsnyk.*writes — unavoidable without middleware, harmless since LS handles it idempotently;http.*does not trigger itauthenticationService.ts— endpoint guardAdds
authFlowUpdatingEndpointstatic flag. Set totruewhilesetEndpoint()runs duringupdateTokenAndEndpoint, cleared infinally. External callers (e.g.MessageHandlerFactory) can also set/clear it viasetAuthFlowUpdatingEndpoint().configurationWatcher.tsChecks
AuthenticationService.isAuthFlowUpdatingEndpoint()before clearing the token on endpoint change.languageServer.ts$/snyk.hasAuthenticatedhandler passesapiUrlalongsidetokentosetAuthToken(token, apiUrl)on the webview provider.htmlInjectionService.ts/workspaceConfigurationWebviewProvider.tssetAuthToken(token, apiUrl)forwarding: webview provider posts{ type: 'setAuthToken', token, apiUrl }; injection service listener callswindow.setAuthToken(message.token, message.apiUrl).commandController.tsinitiateLogin()passesgetAuthenticationMethod(),snykApiEndpoint,getInsecure()as args toSNYK_LOGIN_COMMAND— ensures command-palette login also sends auth params to LS.Tests
messageHandlerFactory.test.ts: 5 new login-args-persist tests (method mapping, endpoint guard, insecure, no-op on <3 args)authenticationService.test.ts: 3 new guard-flag tests (true during call, false after, false after error)executeCommandBridge.test.ts: new unit tests for the shared bridge classhtmlInjectionService.test.ts:__ideExecuteCommand__injection present, deprecated functions absentcommandController.test.ts: auth params forwarded to login commandTest plan
npm test