From 72912d4f39e0ac0bf8c8855b4ea9cc0b4dfa2970 Mon Sep 17 00:00:00 2001 From: Huanyi Xie <74809554+xiehuanyi@users.noreply.github.com> Date: Tue, 6 Oct 2026 21:54:26 +0300 Subject: [PATCH] fix: preserve colons in parsed auth passwords --- src/parse.ts | 4 +++- test/parse.test.ts | 17 ++++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/parse.ts b/src/parse.ts index b2a2e7e0..b08dfdd9 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -131,7 +131,9 @@ export function parsePath(input = ""): ParsedPath { * @returns An object with two properties: username and password. */ export function parseAuth(input = ""): ParsedAuth { - const [username, password] = input.split(":"); + const separator = input.indexOf(":"); + const username = separator === -1 ? input : input.slice(0, separator); + const password = separator === -1 ? "" : input.slice(separator + 1); return { username: decode(username), password: decode(password), diff --git a/test/parse.test.ts b/test/parse.test.ts index ba72667a..d1ec3559 100644 --- a/test/parse.test.ts +++ b/test/parse.test.ts @@ -1,5 +1,5 @@ import { describe, expect, test } from "vitest"; -import { parseURL, parseHost, parseFilename } from "../src"; +import { parseURL, parseHost, parseFilename, parseAuth } from "../src"; describe("parseURL", () => { const tests = [ @@ -294,3 +294,18 @@ describe("parseFilename", () => { }); } }); + +describe("parseAuth", () => { + test.each([ + ["user:pass:word", { username: "user", password: "pass:word" }], + ["user::pass:", { username: "user", password: ":pass:" }], + ["user:pass%3Aword:tail", { username: "user", password: "pass:word:tail" }], + ["user:pass", { username: "user", password: "pass" }], + ["user", { username: "user", password: "" }], + ])( + "preserves the password after the first colon in %s", + (input, expected) => { + expect(parseAuth(input)).toEqual(expected); + }, + ); +});