Skip to content

Commit 2d64031

Browse files
author
Offensive360
committed
Offensive360 SAST plugin.
1 parent 29ad1c7 commit 2d64031

3 files changed

Lines changed: 63 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
All notable changes to the O360 SAST extension will be documented in this file.
44

5+
## [1.1.11] - 2026-04-14
6+
7+
### Added
8+
- Background update check on activation. The extension now polls the GitHub release feed once per day and prompts you when a new version is available, independent of the marketplace. Useful in air-gapped or proxied environments where marketplace auto-updates are blocked.
9+
510
## [1.1.10] - 2026-04-14
611

712
### Fixed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "offensive360",
33
"displayName": "O360 SAST",
44
"description": "Enterprise static application security testing — find and fix vulnerabilities directly in your editor",
5-
"version": "1.1.10",
5+
"version": "1.1.11",
66
"publisher": "Offensive360",
77
"license": "SEE LICENSE IN offensive-license-terms.md",
88
"repository": {

src/extension.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,10 @@ export function activate(context: vscode.ExtensionContext) {
231231
handleScanResults(result, path.dirname(document.uri.fsPath));
232232
}));
233233

234+
// ── Auto update notifier (independent of the marketplace) ─
235+
236+
autoCheckForUpdates(context).catch(() => { /* silent */ });
237+
234238
// ── Disposables ──────────────────────────────────────────
235239

236240
context.subscriptions.push(
@@ -244,6 +248,59 @@ export function activate(context: vscode.ExtensionContext) {
244248
);
245249
}
246250

251+
/**
252+
* Background, throttled update check that goes directly to GitHub Releases
253+
* — independent of the VS Code marketplace. Fires on activation, throttled
254+
* to once per 24 h, silent on any failure.
255+
*/
256+
async function autoCheckForUpdates(context: vscode.ExtensionContext): Promise<void> {
257+
const LAST_CHECK_KEY = 'o360.lastUpdateCheckMs';
258+
const TTL_MS = 24 * 60 * 60 * 1000;
259+
260+
const lastCheck = context.globalState.get<number>(LAST_CHECK_KEY, 0);
261+
if (Date.now() - lastCheck < TTL_MS) return;
262+
context.globalState.update(LAST_CHECK_KEY, Date.now());
263+
264+
const currentVersion: string = context.extension.packageJSON.version || '0.0.0';
265+
const apiUrl = 'https://api.github.com/repos/offensive360/VSCode/releases/latest';
266+
try {
267+
const https = await import('https');
268+
const body: string = await new Promise((resolve, reject) => {
269+
const req = https.get(apiUrl, {
270+
headers: { 'User-Agent': `Offensive360-VSCode/${currentVersion}`, 'Accept': 'application/vnd.github+json' },
271+
timeout: 10000,
272+
}, (res) => {
273+
if (res.statusCode !== 200) { reject(new Error(`HTTP ${res.statusCode}`)); return; }
274+
let data = '';
275+
res.on('data', (chunk: string) => data += chunk);
276+
res.on('end', () => resolve(data));
277+
});
278+
req.on('error', reject);
279+
req.on('timeout', () => { req.destroy(); reject(new Error('Timeout')); });
280+
});
281+
const release = JSON.parse(body);
282+
if (release.draft || release.prerelease) return;
283+
const latestVersion = String(release.tag_name || '').replace(/^v/i, '');
284+
if (!latestVersion) return;
285+
const isNewer = latestVersion.localeCompare(currentVersion, undefined, { numeric: true }) > 0;
286+
if (!isNewer) return;
287+
288+
const action = await vscode.window.showInformationMessage(
289+
`Offensive 360: v${latestVersion} is available (you have v${currentVersion}).`,
290+
'Download', 'Later'
291+
);
292+
if (action === 'Download') {
293+
// Prefer direct .vsix asset if present, otherwise the release page
294+
const assets: any[] = release.assets || [];
295+
const vsix = assets.find(a => typeof a?.name === 'string' && a.name.toLowerCase().endsWith('.vsix'));
296+
const url = vsix?.browser_download_url || release.html_url || `https://github.com/offensive360/VSCode/releases/tag/v${latestVersion}`;
297+
vscode.env.openExternal(vscode.Uri.parse(url));
298+
}
299+
} catch {
300+
// Silent: update notifications must not surface errors to the user.
301+
}
302+
}
303+
247304
function updateStatusBar(count: number, scanning: boolean) {
248305
if (scanning) {
249306
statusBarItem.text = `$(sync~spin) ${EXTENSION_NAME}: Scanning...`;

0 commit comments

Comments
 (0)