Skip to content

Commit

Permalink
Ensure passwords in hosted Git URLs are correctly escaped
Browse files Browse the repository at this point in the history
PR-URL: #58
Credit: @stevenhilder
Close: #58
Reviewed-by: @darcyclarke
  • Loading branch information
stevenhilder authored and darcyclarke committed Feb 25, 2020
1 parent 4636ac9 commit 31140a7
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 2 deletions.
12 changes: 10 additions & 2 deletions index.js
Expand Up @@ -47,7 +47,7 @@ function fromUrl (giturl, opts) {
var gitHostInfo = gitHosts[gitHostName]
var auth = null
if (parsed.auth && authProtocols[parsed.protocol]) {
auth = decodeURIComponent(parsed.auth)
auth = parsed.auth
}
var committish = parsed.hash ? decodeURIComponent(parsed.hash.substr(1)) : null
var user = null
Expand Down Expand Up @@ -106,7 +106,15 @@ function fixupUnqualifiedGist (giturl) {

function parseGitUrl (giturl) {
var matched = giturl.match(/^([^@]+)@([^:/]+):[/]?((?:[^/]+[/])?[^/]+?)(?:[.]git)?(#.*)?$/)
if (!matched) return url.parse(giturl)
if (!matched) {
var legacy = url.parse(giturl)
if (legacy.auth) {
var whatwg = new url.URL(giturl)
legacy.auth = whatwg.username || ''
if (whatwg.password) legacy.auth += ':' + whatwg.password
}
return legacy
}
return {
protocol: 'git+ssh:',
slashes: true,
Expand Down
18 changes: 18 additions & 0 deletions test/auth.js
@@ -0,0 +1,18 @@
var HostedGitInfo = require('../')

var tap = require('tap')
var url = require('url')

// Auth credentials with special characters (colon and/or at-sign) should remain correctly escaped
var parsedInfo = HostedGitInfo.fromUrl('https://user%3An%40me:p%40ss%3Aword@github.com/npm/hosted-git-info.git')
tap.equal(parsedInfo.auth, 'user%3An%40me:p%40ss%3Aword')

// Node.js' built-in `url` module should be able to parse the resulting url
var parsedUrl = new url.URL(parsedInfo.toString())
tap.equal(parsedUrl.username, 'user%3An%40me')
tap.equal(parsedUrl.password, 'p%40ss%3Aword')
tap.equal(parsedUrl.hostname, 'github.com')

// For full backwards-compatibility; support auth where only username or only password is provided
tap.equal(HostedGitInfo.fromUrl('https://user%3An%40me@github.com/npm/hosted-git-info.git').auth, 'user%3An%40me')
tap.equal(HostedGitInfo.fromUrl('https://:p%40ss%3Aword@github.com/npm/hosted-git-info.git').auth, ':p%40ss%3Aword')

0 comments on commit 31140a7

Please sign in to comment.