plugins: don't require a literal .git suffix on a catalogue clone URL
Found chasing a real install failure: music's marketplace row was hand- entered as https://gitea.officer.dev/plugins/music with no .git suffix, and fetchPlugin's URL check refused it outright with a message ("https URLs only, no credentials") that named neither actual reason. The suffix was never a security property — https-only, safe character set, no embedded credentials are the real checks, and Gitea/GitHub both clone identically with or without .git. Made the suffix optional rather than required, so a future hand-entered row missing it doesn't hit the same wall. Also fixed the row itself in officer_marketplace (added .git, matching every other plugin's entry) for consistency, and confirmed the gitea repo itself was never the problem — plugins/music already exists there with both commits, unaffected by this bug. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -56,7 +56,14 @@ export async function fetchPlugin(appName: string, onLog?: OnLog): Promise<Fetch
|
||||
// The URL comes from the catalogue and reaches a command line, so it is checked rather than trusted.
|
||||
// Deliberately narrow: https only, no credentials in the URL, no shell metacharacters. A private
|
||||
// plugin needing auth is a separate feature and must not arrive by someone putting a token in here.
|
||||
if (!/^https:\/\/[A-Za-z0-9._~\-/]+\.git$/.test(entry.source)) {
|
||||
//
|
||||
// `.git` is OPTIONAL, not required — Gitea and GitHub both clone identically with or without it, so
|
||||
// requiring the suffix enforces a naming convention, not a security property. Found the hard way:
|
||||
// music's own marketplace row was hand-entered as `.../plugins/music`, no suffix, and this regex
|
||||
// refused a completely valid, credential-free, https clone URL with a message ("https URLs only, no
|
||||
// credentials") that describes neither actual reason. Row fixed for consistency with its siblings, but
|
||||
// the regex should never have depended on it.
|
||||
if (!/^https:\/\/[A-Za-z0-9._~\-/]+(\.git)?$/.test(entry.source)) {
|
||||
return { ok: false, dir, error: `refusing to clone from "${entry.source}" — https URLs only, no credentials` };
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user