Skip to content

Commit c6f123f

Browse files
committed
fix: harden plugin source intake
1 parent d7f5297 commit c6f123f

9 files changed

Lines changed: 208 additions & 27 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,6 @@ dist-ssr
2222
*.njsproj
2323
*.sln
2424
*.sw?
25+
26+
# dora code context index
27+
.dora/

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,9 @@ src-tauri/target/release/bundle/deb/
8080

8181
| step | behavior |
8282
| --- | --- |
83-
| add plugin | register a local source file, local plugin folder, or HTTPS GitHub repo after validating the Vencord plugin entrypoint |
83+
| add plugin | paste or drop a local source file, local plugin folder, or HTTPS GitHub repo after validating the Vencord plugin entrypoint |
8484
| build | clone or update `Vendicated/Vencord`, recreate `src/userplugins`, run `pnpm install --frozen-lockfile`, then `pnpm build` |
85-
| validate | require `package.json`, `vencordDesktopMain.js`, `vencordDesktopPreload.js`, `vencordDesktopRenderer.js`, `vencordDesktopRenderer.css` |
85+
| validate | require `vencordDesktopMain.js`, `vencordDesktopPreload.js`, `vencordDesktopRenderer.js`, `vencordDesktopRenderer.css` |
8686
| apply | write the validated `dist` path to Vesktop `state.json` as `vencordDir` |
8787
| startup check | optionally launch at login, check the managed Vencord checkout, and rebuild/apply only when Auto rebuild is enabled |
8888
| restart | fully restart Vesktop so it loads the custom Vencord build |

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "veskforge",
33
"private": true,
4-
"version": "0.1.13",
4+
"version": "0.1.14",
55
"description": "Unofficial custom Vencord build manager for Vesktop.",
66
"license": "MIT",
77
"type": "module",

src-tauri/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src-tauri/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "veskforge"
3-
version = "0.1.13"
3+
version = "0.1.14"
44
description = "Unofficial custom Vencord build manager for Vesktop."
55
authors = ["Microck"]
66
license = "MIT"

src-tauri/src/lib.rs

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ use tauri::{AppHandle, Manager};
1212

1313
const VENCORD_REPO: &str = "https://github.com/Vendicated/Vencord.git";
1414
const MANIFEST_FILE: &str = "manifest.json";
15-
const REQUIRED_DIST_FILES: [&str; 5] = [
16-
"package.json",
15+
const REQUIRED_DIST_FILES: [&str; 4] = [
1716
"vencordDesktopMain.js",
1817
"vencordDesktopPreload.js",
1918
"vencordDesktopRenderer.js",
@@ -274,8 +273,21 @@ fn plugin_name_from_source(source: &PluginSource, fallback: Option<String>) -> S
274273
}
275274
}
276275

276+
fn trim_wrapping_quotes(input: &str) -> String {
277+
let trimmed = input.trim();
278+
if trimmed.len() >= 2 {
279+
let bytes = trimmed.as_bytes();
280+
let first = bytes[0];
281+
let last = bytes[bytes.len() - 1];
282+
if (first == b'"' && last == b'"') || (first == b'\'' && last == b'\'') {
283+
return trimmed[1..trimmed.len() - 1].trim().to_string();
284+
}
285+
}
286+
trimmed.to_string()
287+
}
288+
277289
fn normalize_github_plugin_url(url: &str) -> Result<String, String> {
278-
let trimmed = url.trim();
290+
let trimmed = trim_wrapping_quotes(url);
279291
let without_scheme = trimmed
280292
.strip_prefix("https://github.com/")
281293
.ok_or_else(|| "Git plugin sources must be HTTPS GitHub repository URLs.".to_string())?;
@@ -1063,10 +1075,12 @@ fn get_environment_status(app: AppHandle) -> Result<EnvironmentStatus, String> {
10631075
fn add_plugin(app: AppHandle, request: AddPluginRequest) -> Result<Manifest, String> {
10641076
let source = match request.source {
10651077
PluginSource::LocalFile { path } => {
1078+
let path = trim_wrapping_quotes(&path);
10661079
validate_local_plugin_path(Path::new(&path))?;
10671080
PluginSource::LocalFile { path }
10681081
}
10691082
PluginSource::LocalFolder { path } => {
1083+
let path = trim_wrapping_quotes(&path);
10701084
validate_local_plugin_path(Path::new(&path))?;
10711085
PluginSource::LocalFolder { path }
10721086
}
@@ -1430,6 +1444,32 @@ mod tests {
14301444
);
14311445
}
14321446

1447+
#[test]
1448+
fn source_inputs_trim_wrapping_quotes() {
1449+
assert_eq!(
1450+
trim_wrapping_quotes(r#""D:\Descargas\jn v2\discord-gfm-tables.plugin.js""#),
1451+
r#"D:\Descargas\jn v2\discord-gfm-tables.plugin.js"#
1452+
);
1453+
assert_eq!(
1454+
normalize_github_plugin_url("'https://github.com/Microck/discord-gfm-tables'").unwrap(),
1455+
"https://github.com/Microck/discord-gfm-tables.git"
1456+
);
1457+
}
1458+
1459+
#[test]
1460+
fn dist_validation_matches_current_vencord_desktop_outputs() {
1461+
let dir = env::temp_dir().join(format!("veskforge-dist-test-{}", now_stamp()));
1462+
fs::create_dir_all(&dir).unwrap();
1463+
for file in REQUIRED_DIST_FILES {
1464+
fs::write(dir.join(file), "").unwrap();
1465+
}
1466+
1467+
assert!(validate_dist(&dir).is_ok());
1468+
assert!(!REQUIRED_DIST_FILES.contains(&"package.json"));
1469+
1470+
fs::remove_dir_all(dir).unwrap();
1471+
}
1472+
14331473
#[test]
14341474
fn materialized_plugin_requires_index_entrypoint() {
14351475
let dir = env::temp_dir().join(format!("veskforge-entrypoint-test-{}", now_stamp()));

src-tauri/tauri.conf.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "https://schema.tauri.app/config/2",
33
"productName": "Veskforge",
4-
"version": "0.1.13",
4+
"version": "0.1.14",
55
"identifier": "dev.micr.veskforge",
66
"build": {
77
"beforeDevCommand": "pnpm dev",

src/App.css

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,9 @@ button:disabled {
496496
color: #f4f5f8;
497497
background: rgba(18, 22, 28, 0.46);
498498
font-size: 16px;
499+
transition:
500+
border-color 160ms var(--ease),
501+
background 160ms var(--ease);
499502
}
500503

501504
.drop-panel > span {
@@ -508,6 +511,13 @@ button:disabled {
508511
padding: 14px;
509512
}
510513

514+
.drop-panel.drag-active {
515+
border-color: rgba(236, 118, 151, 0.72);
516+
background:
517+
linear-gradient(180deg, rgba(236, 118, 151, 0.12), rgba(236, 118, 151, 0.04)),
518+
rgba(18, 22, 28, 0.7);
519+
}
520+
511521
.source-feedback {
512522
display: flex;
513523
align-items: flex-start;

0 commit comments

Comments
 (0)