From 665fe34f6119238b45480bcaa9922c42b47a2af3 Mon Sep 17 00:00:00 2001 From: GeekMasher Date: Thu, 4 Sep 2025 14:28:31 +0100 Subject: [PATCH 1/8] fix: Update and remove GeekMasher from Codeowner --- .github/CODEOWNERS | 4 +++- .github/dependabot.yml | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 .github/dependabot.yml diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index bcc4f88..9a120d6 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1,3 @@ -* @GeekMasher +# Codeowners + +* @advanced-security/oss-maintainers diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..b68db60 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,42 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + reviewers: + - "advanced-security/oss-maintainers" + target-branch: "main" + commit-message: + prefix: deps + prefix-development: chore + labels: + - "Dependencies" + groups: + production-dependencies: + dependency-type: "production" + development-dependencies: + dependency-type: "development" + + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "weekly" + reviewers: + - "advanced-security/oss-maintainers" + target-branch: "main" + commit-message: + prefix: deps + prefix-development: chore + labels: + - "Dependencies" + groups: + production-dependencies: + dependency-type: "production" + development-dependencies: + dependency-type: "development" From b5a645ce8d0cfe3f2f1b96e34a6f39126efd13f2 Mon Sep 17 00:00:00 2001 From: GeekMasher Date: Wed, 10 Sep 2025 11:30:50 +0100 Subject: [PATCH 2/8] feat: Add CodeQL status check and repository info update functionality --- src/providers/uiProvider.ts | 644 ++++++++++++++++++++++++++++++++-- src/services/githubService.ts | 42 +++ 2 files changed, 664 insertions(+), 22 deletions(-) diff --git a/src/providers/uiProvider.ts b/src/providers/uiProvider.ts index 8aeb14c..ee59b6a 100644 --- a/src/providers/uiProvider.ts +++ b/src/providers/uiProvider.ts @@ -57,6 +57,12 @@ export class UiProvider implements vscode.WebviewViewProvider { case "testConnection": this.testGitHubConnection(); break; + case "checkCodeQLEnabled": + this.checkCodeQLEnabled(); + break; + case "updateRepositoryInfo": + this.updateRepositoryInfo(message.owner, message.repo); + break; case "runLocalScan": this.runLocalScan(); break; @@ -164,6 +170,39 @@ export class UiProvider implements vscode.WebviewViewProvider { ); } this.logger.info("UiProvider", `Using threat model: ${threatModel}`); + + // Check if CodeQL is enabled for the configured repository + const owner = config.get("github.owner"); + const repo = config.get("github.repo"); + if (owner && repo) { + this.logger.info( + "UiProvider", + `Checking CodeQL status during configuration load for ${owner}/${repo}` + ); + + // We'll check CodeQL status, but won't block configuration loading + this.checkCodeQLEnabled() + .then(isEnabled => { + this.logger.info( + "UiProvider", + `CodeQL status check during configuration load: ${isEnabled ? 'ENABLED' : 'NOT ENABLED'} for ${owner}/${repo}`, + { owner, repo, codeqlEnabled: isEnabled } + ); + }) + .catch(error => { + this.logger.warn( + "UiProvider", + "Failed to check CodeQL status during configuration load", + error + ); + }); + } else { + this.logger.info( + "UiProvider", + "Skipping CodeQL status check - repository information not configured", + { owner, repo } + ); + } // Auto-select GitHub repository languages if no manual selection exists let languages = config.get("languages", []); @@ -438,6 +477,36 @@ export class UiProvider implements vscode.WebviewViewProvider { return; } + // Check if CodeQL is enabled for the repository + const config = vscode.workspace.getConfiguration("codeql-scanner"); + const owner = config.get("github.owner"); + const repo = config.get("github.repo"); + + if (!owner || !repo) { + this.logger.warn("UiProvider", "Repository information not configured"); + this._view?.webview.postMessage({ + command: "scanBlocked", + success: false, + message: "Repository information not configured. Please set up your repository connection first.", + }); + return; + } + + try { + const isEnabled = await this._githubService.isCodeQLEnabled(owner, repo); + if (!isEnabled) { + this.logger.warn("UiProvider", `CodeQL is not enabled for ${owner}/${repo}`); + this._view?.webview.postMessage({ + command: "scanBlocked", + success: false, + message: `CodeQL is not enabled for ${owner}/${repo}. Please enable CodeQL in your repository settings.`, + }); + return; + } + } catch (error) { + this.logger.warn("UiProvider", "Failed to check if CodeQL is enabled", error); + } + try { // Set scan in progress flag this._scanInProgress = true; @@ -481,10 +550,20 @@ export class UiProvider implements vscode.WebviewViewProvider { } } + /** + * Fetch remote CodeQL alerts from GitHub for the configured repository + * Requires CodeQL to be enabled on the repository + */ private async fetchRemoteAlerts() { + this.logger.logServiceCall("UiProvider", "fetchRemoteAlerts", "started"); + // Check if a scan is already in progress if (this._scanInProgress) { - this.logger.warn("UiProvider", "Attempted to fetch alerts while a scan is in progress"); + this.logger.warn( + "UiProvider", + "Attempted to fetch alerts while a scan is in progress", + { scanInProgress: this._scanInProgress } + ); // Send message to UI this._view?.webview.postMessage({ @@ -499,11 +578,82 @@ export class UiProvider implements vscode.WebviewViewProvider { return; } + // Check if repository information is configured + const config = vscode.workspace.getConfiguration("codeql-scanner"); + const owner = config.get("github.owner"); + const repo = config.get("github.repo"); + + this.logger.info( + "UiProvider", + "Fetching remote alerts with repository configuration", + { owner, repo } + ); + + if (!owner || !repo) { + this.logger.warn( + "UiProvider", + "Repository information not configured for fetching alerts" + ); + this._view?.webview.postMessage({ + command: "fetchBlocked", + success: false, + message: "Repository information not configured. Please set up your repository connection first.", + }); + return; + } + + // Check if CodeQL is enabled for the repository + try { + this.logger.info( + "UiProvider", + `Checking if CodeQL is enabled for ${owner}/${repo} before fetching alerts` + ); + + const isEnabled = await this._githubService.isCodeQLEnabled(owner, repo); + + if (!isEnabled) { + this.logger.warn( + "UiProvider", + `CodeQL is not enabled for ${owner}/${repo}, cannot fetch alerts`, + { owner, repo, codeqlEnabled: false } + ); + this._view?.webview.postMessage({ + command: "fetchBlocked", + success: false, + message: `CodeQL is not enabled for ${owner}/${repo}. Please enable CodeQL in your repository settings.`, + }); + return; + } + + this.logger.info( + "UiProvider", + `CodeQL is enabled for ${owner}/${repo}, proceeding with alert fetch` + ); + } catch (error) { + this.logger.warn( + "UiProvider", + "Failed to check if CodeQL is enabled before fetching alerts", + error + ); + } + // Set scan in progress flag for the duration of the fetch this._scanInProgress = true; + this.logger.debug( + "UiProvider", + "Setting scan in progress flag for fetch operation", + { scanInProgress: this._scanInProgress } + ); + try { this._fetchStartTime = Date.now(); + + this.logger.debug( + "UiProvider", + "Starting fetch operation timer", + { fetchStartTime: this._fetchStartTime } + ); this._view?.webview.postMessage({ command: "fetchStarted", @@ -516,46 +666,95 @@ export class UiProvider implements vscode.WebviewViewProvider { const owner = config.get("github.owner"); const repo = config.get("github.repo"); + this.logger.debug( + "UiProvider", + "Verifying GitHub configuration for alert fetch", + { + hasToken: !!token, + owner, + repo + } + ); + if (!token || !owner || !repo) { - throw new Error( + const error = new Error( "GitHub configuration is incomplete. Please configure token, owner, and repo." ); + this.logger.error("UiProvider", "GitHub configuration incomplete for alert fetch", error); + throw error; } // Update the service with the current token + this.logger.debug("UiProvider", "Updating GitHub token for alert fetch"); this._githubService.updateToken(token); // Use GitHubService to fetch CodeQL alerts + this.logger.info( + "UiProvider", + `Fetching CodeQL alerts from GitHub for ${owner}/${repo}` + ); + const codeqlAlerts = await this._githubService.getCodeQLAlerts( owner, repo ); + + this.logger.info( + "UiProvider", + `Retrieved ${codeqlAlerts.length} CodeQL alerts from GitHub`, + { alertCount: codeqlAlerts.length } + ); // Convert GitHub alerts to our ScanResult format - const scanResults = codeqlAlerts.map((alert: any) => ({ - ruleId: alert.rule?.id || "unknown", - severity: this.mapGitHubSeverityToLocal( + this.logger.debug( + "UiProvider", + "Converting GitHub alerts to ScanResult format" + ); + + const scanResults = codeqlAlerts.map((alert: any) => { + const severity = this.mapGitHubSeverityToLocal( alert.rule?.security_severity_level || alert.rule?.severity - ), - language: this.mapCodeQLAlertLanguage(alert.rule?.id), - message: - alert.message?.text || alert.rule?.description || "No description", - location: { - file: alert.most_recent_instance?.location?.path - ? path.join(vscode.workspace.workspaceFolders?.[0]?.uri.fsPath || "", alert.most_recent_instance.location.path) - : "unknown", - startLine: alert.most_recent_instance?.location?.start_line || 1, - startColumn: alert.most_recent_instance?.location?.start_column || 1, - endLine: alert.most_recent_instance?.location?.end_line || 1, - endColumn: alert.most_recent_instance?.location?.end_column || 1, - }, - })); + ); + const language = this.mapCodeQLAlertLanguage(alert.rule?.id); + + return { + ruleId: alert.rule?.id || "unknown", + severity: severity, + language: language, + message: + alert.message?.text || alert.rule?.description || "No description", + location: { + file: alert.most_recent_instance?.location?.path + ? path.join(vscode.workspace.workspaceFolders?.[0]?.uri.fsPath || "", alert.most_recent_instance.location.path) + : "unknown", + startLine: alert.most_recent_instance?.location?.start_line || 1, + startColumn: alert.most_recent_instance?.location?.start_column || 1, + endLine: alert.most_recent_instance?.location?.end_line || 1, + endColumn: alert.most_recent_instance?.location?.end_column || 1, + }, + }; + }); + + this.logger.info( + "UiProvider", + `Converted ${scanResults.length} GitHub alerts to ScanResult format`, + { + resultCount: scanResults.length + } + ); // Update the scan results and refresh summary + this.logger.debug("UiProvider", "Updating scan results with fetched alerts"); this.updateScanResults(scanResults); // Also update the results provider if available if (this._resultsProvider) { + this.logger.debug( + "UiProvider", + "Updating results provider with fetched alerts", + { resultsCount: scanResults.length } + ); + this._resultsProvider.setResults(scanResults); vscode.commands.executeCommand( "setContext", @@ -568,6 +767,15 @@ export class UiProvider implements vscode.WebviewViewProvider { ? Date.now() - this._fetchStartTime : 0; const durationText = this.formatDuration(fetchDuration); + + this.logger.info( + "UiProvider", + `Fetch operation completed in ${durationText}`, + { + fetchDuration, + alertsCount: scanResults.length + } + ); this._view?.webview.postMessage({ command: "fetchCompleted", @@ -580,6 +788,12 @@ export class UiProvider implements vscode.WebviewViewProvider { ? Date.now() - this._fetchStartTime : 0; const durationText = this.formatDuration(fetchDuration); + + this.logger.error( + "UiProvider", + `Failed to fetch remote alerts after ${durationText}`, + error + ); this._view?.webview.postMessage({ command: "fetchCompleted", @@ -590,6 +804,18 @@ export class UiProvider implements vscode.WebviewViewProvider { } finally { // Reset scan in progress flag regardless of success or failure this._scanInProgress = false; + + this.logger.debug( + "UiProvider", + "Resetting scan in progress flag after fetch operation", + { scanInProgress: false } + ); + + this.logger.logServiceCall( + "UiProvider", + "fetchRemoteAlerts", + "completed" + ); } } @@ -750,6 +976,239 @@ export class UiProvider implements vscode.WebviewViewProvider { : `${hours}h`; } + /** + * Check if CodeQL is enabled on the configured GitHub repository + * This prevents scanning when CodeQL is not enabled + * Sets VS Code context to control UI visibility based on CodeQL status + */ + private async checkCodeQLEnabled(): Promise { + this.logger.logServiceCall("UiProvider", "checkCodeQLEnabled", "started"); + + const config = vscode.workspace.getConfiguration("codeql-scanner"); + const token = config.get("github.token"); + const owner = config.get("github.owner"); + const repo = config.get("github.repo"); + + this.logger.info( + "UiProvider", + "Checking CodeQL status for repository", + { owner, repo, tokenConfigured: !!token } + ); + + // Default to hiding scanning UI if we can't verify CodeQL status + await vscode.commands.executeCommand('setContext', 'codeql-scanner.codeQLEnabled', false); + + this.logger.debug("UiProvider", "Setting CodeQL enabled context to false by default"); + + if (!token) { + this.logger.warn( + "UiProvider", + "GitHub token not configured for checking CodeQL status" + ); + this._view?.webview.postMessage({ + command: "codeqlStatusChecked", + success: false, + enabled: false, + message: "GitHub token is required", + owner: owner || "", + repo: repo || "", + }); + return false; + } + + if (!owner || !repo) { + this.logger.warn( + "UiProvider", + "GitHub repository information not configured", + { owner, repo } + ); + this._view?.webview.postMessage({ + command: "codeqlStatusChecked", + success: false, + enabled: false, + message: "Repository owner and name must be configured", + owner: owner || "", + repo: repo || "", + }); + return false; + } + + try { + this.logger.debug( + "UiProvider", + "Updating GitHub token for CodeQL status check" + ); + + // Update the service with the current token + this._githubService.updateToken(token); + + this.logger.info( + "UiProvider", + `Checking if CodeQL is enabled for ${owner}/${repo}` + ); + + // Check if CodeQL is enabled + const isEnabled = await this._githubService.isCodeQLEnabled(owner, repo); + + this.logger.logServiceCall( + "UiProvider", + "checkCodeQLEnabled", + "completed", + { owner, repo, enabled: isEnabled } + ); + + this.logger.info( + "UiProvider", + `CodeQL status check result: ${isEnabled ? 'ENABLED' : 'NOT ENABLED'} for ${owner}/${repo}` + ); + + // Update VS Code context to control UI visibility based on CodeQL status + await vscode.commands.executeCommand('setContext', 'codeql-scanner.codeQLEnabled', isEnabled); + + this.logger.info( + "UiProvider", + `Setting CodeQL enabled context to ${isEnabled}`, + { contextUpdated: true, codeQLEnabled: isEnabled } + ); + + this._view?.webview.postMessage({ + command: "codeqlStatusChecked", + success: true, + enabled: isEnabled, + message: isEnabled ? + `CodeQL is enabled for ${owner}/${repo}` : + `CodeQL is not enabled for ${owner}/${repo}. Scanning functionality is disabled.`, + owner: owner || "", + repo: repo || "", + }); + + return isEnabled; + } catch (error) { + this.logger.logServiceCall( + "UiProvider", + "checkCodeQLEnabled", + "failed", + error + ); + + this.logger.error( + "UiProvider", + `Failed to check CodeQL status for ${owner}/${repo}`, + error + ); + this._view?.webview.postMessage({ + command: "codeqlStatusChecked", + success: false, + enabled: false, + message: `Failed to check CodeQL status: ${error}`, + owner: owner || "", + repo: repo || "", + }); + return false; + } + } + + /** + * Update repository information when provided from the UI + * Updates the configuration settings and checks if CodeQL is enabled + * + * @param owner Repository owner + * @param repo Repository name + */ + private async updateRepositoryInfo(owner: string, repo: string): Promise { + this.logger.logServiceCall("UiProvider", "updateRepositoryInfo", "started", { + owner, repo + }); + + if (!owner || !repo) { + this.logger.warn( + "UiProvider", + "Invalid repository information provided", + { providedOwner: owner, providedRepo: repo } + ); + this._view?.webview.postMessage({ + command: "repositoryInfoUpdated", + success: false, + message: "Repository owner and name must be provided", + }); + return; + } + + const config = vscode.workspace.getConfiguration("codeql-scanner"); + const oldOwner = config.get("github.owner"); + const oldRepo = config.get("github.repo"); + + this.logger.debug( + "UiProvider", + "Updating repository information", + { + oldOwner, + oldRepo, + newOwner: owner, + newRepo: repo + } + ); + + try { + // Update repository settings + this.logger.debug("UiProvider", "Updating github.owner setting", { owner }); + await config.update("github.owner", owner, vscode.ConfigurationTarget.Workspace); + + this.logger.debug("UiProvider", "Updating github.repo setting", { repo }); + await config.update("github.repo", repo, vscode.ConfigurationTarget.Workspace); + + this.logger.info( + "UiProvider", + `Repository information updated from ${oldOwner}/${oldRepo} to ${owner}/${repo}` + ); + + this.logger.info( + "UiProvider", + "Checking CodeQL status for the updated repository" + ); + + // Check if CodeQL is enabled on the updated repository + const codeqlStatus = await this.checkCodeQLEnabled(); + + this.logger.info( + "UiProvider", + `CodeQL status for updated repository ${owner}/${repo}: ${codeqlStatus ? 'ENABLED' : 'NOT ENABLED'}` + ); + + this.logger.logServiceCall( + "UiProvider", + "updateRepositoryInfo", + "completed", + { owner, repo, codeqlEnabled: codeqlStatus } + ); + + this._view?.webview.postMessage({ + command: "repositoryInfoUpdated", + success: true, + message: `Repository information updated to ${owner}/${repo}`, + }); + } catch (error) { + this.logger.logServiceCall( + "UiProvider", + "updateRepositoryInfo", + "failed", + error + ); + + this.logger.error( + "UiProvider", + `Failed to update repository information for ${owner}/${repo}`, + error + ); + + this._view?.webview.postMessage({ + command: "repositoryInfoUpdated", + success: false, + message: `Failed to update repository information: ${error}`, + }); + } + } + private _getHtmlForWebview(webview: vscode.Webview) { return ` @@ -1858,6 +2317,35 @@ export class UiProvider implements vscode.WebviewViewProvider { +
+

🔗 GitHub Repository

+ + +
+ + +
+ +
+ + +
+ +
+ + +
+
Configure GitHub repository details to enable CodeQL scanning
+
+ -
+

🔍 Scan Configuration

@@ -1963,7 +2451,7 @@ export class UiProvider implements vscode.WebviewViewProvider {
Select the threat model to focus the analysis on specific security scenarios
-
+

🔤 Language Selection

@@ -2205,7 +2693,89 @@ export class UiProvider implements vscode.WebviewViewProvider { } function loadConfig() { - vscode.postMessage({ command: 'loadConfig' }); + vscode.postMessage({ + command: 'loadConfig' + }); + } + + function updateRepositoryInfo() { + const owner = document.getElementById('githubOwner').value.trim(); + const repo = document.getElementById('githubRepo').value.trim(); + + if (!owner || !repo) { + showMessage('Repository owner and name are required', 'error'); + return; + } + + // Disable buttons during update + document.getElementById('updateRepoButton').disabled = true; + document.getElementById('checkCodeQLButton').disabled = true; + + vscode.postMessage({ + command: 'updateRepositoryInfo', + owner: owner, + repo: repo + }); + } + + function checkCodeQLEnabled() { + // Show loading state + const button = document.getElementById('checkCodeQLButton'); + const checkIcon = button.querySelector('.check-icon'); + const checkText = button.querySelector('span:last-child'); + + button.disabled = true; + checkIcon.textContent = '⏳'; + checkText.textContent = 'Checking...'; + + // Clear previous status + const statusMessage = document.getElementById('codeqlStatusMessage'); + statusMessage.style.display = 'none'; + + vscode.postMessage({ + command: 'checkCodeQLEnabled' + }); + } + + function updateCodeQLStatus(success, enabled, message) { + const statusMessage = document.getElementById('codeqlStatusMessage'); + statusMessage.style.display = 'block'; + + if (success) { + if (enabled) { + statusMessage.style.backgroundColor = 'rgba(40, 167, 69, 0.1)'; + statusMessage.style.border = '1px solid #28a745'; + statusMessage.style.color = '#28a745'; + statusMessage.innerHTML = '✅ ' + message; + } else { + statusMessage.style.backgroundColor = 'rgba(255, 193, 7, 0.1)'; + statusMessage.style.border = '1px solid #ffc107'; + statusMessage.style.color = '#ffc107'; + statusMessage.innerHTML = '⚠️ ' + message + '
You must enable CodeQL in repository settings before scanning.'; + } + } else { + statusMessage.style.backgroundColor = 'rgba(220, 53, 69, 0.1)'; + statusMessage.style.border = '1px solid #dc3545'; + statusMessage.style.color = '#dc3545'; + statusMessage.innerHTML = '❌ ' + message; + } + + // Reset check button + const button = document.getElementById('checkCodeQLButton'); + const checkIcon = button.querySelector('.check-icon'); + const checkText = button.querySelector('span:last-child'); + + button.disabled = false; + checkIcon.textContent = '✓'; + checkText.textContent = 'Check CodeQL Status'; + + // Enable update button as well + document.getElementById('updateRepoButton').disabled = false; + } + + function setRepositoryInfo(owner, repo) { + document.getElementById('githubOwner').value = owner || ''; + document.getElementById('githubRepo').value = repo || ''; } function testConnection() { @@ -2565,6 +3135,36 @@ export class UiProvider implements vscode.WebviewViewProvider { case 'alertsSummaryLoaded': updateAlertsSummary(message.summary); break; + + case 'codeqlStatusChecked': + updateCodeQLStatus(message.success, message.enabled, message.message); + setRepositoryInfo(message.owner, message.repo); + + // Update scan and fetch buttons based on CodeQL status + const scanBtn = document.getElementById('scanButton'); + const fetchBtn = document.getElementById('fetchButton'); + + if (message.success && message.enabled) { + scanBtn.disabled = false; + fetchBtn.disabled = false; + } else { + // Only disable buttons if CodeQL is not enabled (don't disable on check failure) + if (message.success) { + scanBtn.disabled = !message.enabled; + fetchBtn.disabled = !message.enabled; + } + } + break; + + case 'repositoryInfoUpdated': + document.getElementById('updateRepoButton').disabled = false; + showMessage(message.message, !message.success); + break; + + case 'scanBlocked': + case 'fetchBlocked': + showMessage(message.message, true); + break; } }); diff --git a/src/services/githubService.ts b/src/services/githubService.ts index e94ce38..e19c0d3 100644 --- a/src/services/githubService.ts +++ b/src/services/githubService.ts @@ -273,6 +273,48 @@ export class GitHubService { } } + /** + * Check if CodeQL is enabled for a repository + * @param owner Repository owner + * @param repo Repository name + * @returns Promise resolving to true if CodeQL is enabled, false otherwise + */ + public async isCodeQLEnabled(owner: string, repo: string): Promise { + this.logger.logServiceCall("GitHubService", "isCodeQLEnabled", "started", { + owner, + repo, + }); + + if (!this.octokit) { + this.logger.warn( + "GitHubService", + "GitHub token not configured for checking CodeQL status" + ); + return false; + } + + try { + const codeqlStatus = await this.getCodeQLStatus(owner, repo); + + this.logger.logServiceCall( + "GitHubService", + "isCodeQLEnabled", + "completed", + { owner, repo, enabled: codeqlStatus } + ); + + return codeqlStatus; + } catch (error) { + this.logger.logServiceCall( + "GitHubService", + "isCodeQLEnabled", + "failed", + error + ); + return false; + } + } + public async triggerCodeQLScan( owner: string, repo: string, From 92087c4de505bf0abadb5777a13197f3259f915a Mon Sep 17 00:00:00 2001 From: GeekMasher Date: Wed, 10 Sep 2025 12:04:22 +0100 Subject: [PATCH 3/8] feat: Update UI for GitHub repository settings with collapsible sections and CodeQL status checks --- package.json | 20 +- src/providers/uiProvider.ts | 377 ++++++++++++++++++++++-------------- 2 files changed, 248 insertions(+), 149 deletions(-) diff --git a/package.json b/package.json index b67a034..52f7b62 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "codeql-scanner-vscode", "displayName": "CodeQL Scanner", "description": "VSCode extension for CodeQL to scan and analyze code for vulnerabilities using GitHub's CodeQL.", - "version": "0.1.2", + "version": "0.2.0", "repository": { "type": "git", "url": "https://github.com/geekmasher/codeql-scanner-vscode.git" @@ -37,17 +37,20 @@ { "command": "codeql-scanner.scan", "title": "CodeQL: Run Scan", - "category": "CodeQL Scanner" + "category": "CodeQL Scanner", + "enablement": "codeql-scanner.codeQLEnabled" }, { "command": "codeql-scanner.init", "title": "CodeQL: Initialize Repository", - "category": "CodeQL Scanner" + "category": "CodeQL Scanner", + "enablement": "codeql-scanner.codeQLEnabled" }, { "command": "codeql-scanner.analysis", "title": "CodeQL: Run Analysis", - "category": "CodeQL Scanner" + "category": "CodeQL Scanner", + "enablement": "codeql-scanner.codeQLEnabled" }, { "command": "codeql-scanner.configure", @@ -194,15 +197,15 @@ "commandPalette": [ { "command": "codeql-scanner.scan", - "when": "workspaceContainsCodeqlConfig || true" + "when": "(workspaceContainsCodeqlConfig || true) && codeql-scanner.codeQLEnabled" }, { "command": "codeql-scanner.init", - "when": "workspaceContainsCodeqlConfig || true" + "when": "(workspaceContainsCodeqlConfig || true) && codeql-scanner.codeQLEnabled" }, { "command": "codeql-scanner.analysis", - "when": "workspaceContainsCodeqlConfig || true" + "when": "(workspaceContainsCodeqlConfig || true) && codeql-scanner.codeQLEnabled" }, { "command": "codeql-scanner.configure", @@ -224,7 +227,8 @@ "explorer/context": [ { "command": "codeql-scanner.scan", - "group": "codeql@1" + "group": "codeql@1", + "when": "codeql-scanner.codeQLEnabled" } ], "view/item/context": [ diff --git a/src/providers/uiProvider.ts b/src/providers/uiProvider.ts index ee59b6a..92b69b4 100644 --- a/src/providers/uiProvider.ts +++ b/src/providers/uiProvider.ts @@ -1628,6 +1628,37 @@ export class UiProvider implements vscode.WebviewViewProvider { color: var(--vscode-foreground); } + /* Collapsible section styles */ + .collapsible-header { + cursor: pointer; + display: flex; + justify-content: space-between; + align-items: center; + padding: 5px 0; + user-select: none; + } + + .collapsible-header .toggle-icon { + transition: transform 0.3s ease; + margin-left: 8px; + font-size: 12px; + } + + .collapsible-header.collapsed .toggle-icon { + transform: rotate(-90deg); + } + + .collapsible-content { + max-height: 1000px; + overflow: hidden; + transition: max-height 0.4s ease; + } + + .collapsible-content.collapsed { + max-height: 0; + overflow: hidden; + } + #message { margin-top: 15px; padding: 10px; @@ -2317,157 +2348,161 @@ export class UiProvider implements vscode.WebviewViewProvider {
-
-

🔗 GitHub Repository

+
+

🔗 GitHub Repository

-
- - -
- -
- - -
- -
- - -
-
Configure GitHub repository details to enable CodeQL scanning
-
- -