feat(electrobun): project wizard phases 1-5 (WIP)
- sanitize.ts: input sanitization (trim, control chars, path traversal) - provider-scanner.ts: detect Claude/Codex/Ollama/Gemini availability - model-fetcher.ts: live model lists from 4 provider APIs - ModelConfigPanel.svelte: per-provider config (thinking, effort, sandbox, temperature) - WizardStep1-3.svelte: split wizard into composable steps - CustomDropdown/Checkbox/Radio: themed UI components - provider-handlers.ts: provider.scan + provider.models RPC - Wire providers into wizard step 3 (live detection + model lists) - Replace native selects in 5 settings panels with CustomDropdown
This commit is contained in:
parent
b7fc3a0f9b
commit
d4014a193d
25 changed files with 2112 additions and 759 deletions
62
ui-electrobun/src/mainview/sanitize.ts
Normal file
62
ui-electrobun/src/mainview/sanitize.ts
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/**
|
||||
* Input sanitization utilities for the Project Wizard.
|
||||
*
|
||||
* All user-supplied strings pass through these before use.
|
||||
*/
|
||||
|
||||
const CONTROL_CHAR_RE = /[\x00-\x1f\x7f]/g;
|
||||
const PATH_TRAVERSAL_RE = /\.\.\//;
|
||||
const GIT_URL_RE = /^(https?:\/\/|git@|ssh:\/\/|git:\/\/).+/;
|
||||
const GITHUB_REPO_RE = /^[\w][\w.-]*\/[\w][\w.-]*$/;
|
||||
|
||||
/**
|
||||
* General string sanitizer: trim, strip control characters, reject path traversal.
|
||||
* Returns null if the input is rejected (contains `../`).
|
||||
*/
|
||||
export function sanitize(str: string): string | null {
|
||||
const trimmed = str.trim().replace(CONTROL_CHAR_RE, '');
|
||||
if (PATH_TRAVERSAL_RE.test(trimmed)) return null;
|
||||
return trimmed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize a URL string. Returns null if the URL is malformed or contains traversal.
|
||||
*/
|
||||
export function sanitizeUrl(url: string): string | null {
|
||||
const clean = sanitize(url);
|
||||
if (!clean) return null;
|
||||
try {
|
||||
// Allow git@ SSH URLs and standard HTTP(S)
|
||||
if (GIT_URL_RE.test(clean)) return clean;
|
||||
new URL(clean);
|
||||
return clean;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize a filesystem path. Rejects `../` traversal attempts.
|
||||
* Allows `~` prefix for home directory expansion (done server-side).
|
||||
*/
|
||||
export function sanitizePath(path: string): string | null {
|
||||
const clean = sanitize(path);
|
||||
if (!clean) return null;
|
||||
// Reject null bytes (extra safety)
|
||||
if (clean.includes('\0')) return null;
|
||||
return clean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a GitHub `owner/repo` string.
|
||||
*/
|
||||
export function isValidGithubRepo(input: string): boolean {
|
||||
return GITHUB_REPO_RE.test(input.trim());
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a Git clone URL (http(s), git@, ssh://, git://).
|
||||
*/
|
||||
export function isValidGitUrl(input: string): boolean {
|
||||
return GIT_URL_RE.test(input.trim());
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue