Skip to content

Commit 6f8fa07

Browse files
committed
Add auth.parse for low-level string parsing
closes #21
1 parent d1b8ee5 commit 6f8fa07

File tree

5 files changed

+118
-17
lines changed

5 files changed

+118
-17
lines changed

HISTORY.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
unreleased
2+
==========
3+
4+
* Add `auth.parse` for low-level string parsing
5+
16
1.0.4 / 2016-05-10
27
==================
38

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Copyright (c) 2013 TJ Holowaychuk
44
Copyright (c) 2014 Jonathan Ong <[email protected]>
5-
Copyright (c) 2015 Douglas Christopher Wilson <[email protected]>
5+
Copyright (c) 2015-2016 Douglas Christopher Wilson <[email protected]>
66

77
Permission is hereby granted, free of charge, to any person obtaining
88
a copy of this software and associated documentation files (the

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ Get the basic auth credentials from the given request. The `Authorization`
3030
header is parsed and if the header is invalid, `undefined` is returned,
3131
otherwise an object with `name` and `pass` properties.
3232

33+
### auth.parse(string)
34+
35+
Parse a basic auth authorization header string. This will return an object
36+
with `name` and `pass` properties, or `undefined` if the string is invalid.
37+
3338
## Example
3439

3540
Pass a node request or koa Context object to the module exported. If
@@ -40,7 +45,14 @@ parsing fails `undefined` is returned, otherwise an object with
4045
var auth = require('basic-auth');
4146
var user = auth(req);
4247
// => { name: 'something', pass: 'whatever' }
48+
```
4349

50+
A header string from any other location can also be parsed with
51+
`auth.parse`, for example a `Proxy-Authorization` header:
52+
53+
```js
54+
var auth = require('basic-auth')
55+
var user = auth.parse(req.getHeader('Proxy-Authorization'))
4456
```
4557

4658
### With vanilla node.js http server

index.js

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* basic-auth
33
* Copyright(c) 2013 TJ Holowaychuk
44
* Copyright(c) 2014 Jonathan Ong
5-
* Copyright(c) 2015 Douglas Christopher Wilson
5+
* Copyright(c) 2015-2016 Douglas Christopher Wilson
66
* MIT Licensed
77
*/
88

@@ -14,6 +14,7 @@
1414
*/
1515

1616
module.exports = auth
17+
module.exports.parse = parse
1718

1819
/**
1920
* RegExp for basic auth credentials
@@ -58,21 +59,7 @@ function auth (req) {
5859
var header = getAuthorization(req.req || req)
5960

6061
// parse header
61-
var match = CREDENTIALS_REGEXP.exec(header || '')
62-
63-
if (!match) {
64-
return
65-
}
66-
67-
// decode user pass
68-
var userPass = USER_PASS_REGEXP.exec(decodeBase64(match[1]))
69-
70-
if (!userPass) {
71-
return
72-
}
73-
74-
// return credentials object
75-
return new Credentials(userPass[1], userPass[2])
62+
return parse(header)
7663
}
7764

7865
/**
@@ -97,6 +84,37 @@ function getAuthorization (req) {
9784
return req.headers.authorization
9885
}
9986

87+
/**
88+
* Parse basic auth to object.
89+
*
90+
* @param {string} string
91+
* @return {object}
92+
* @public
93+
*/
94+
95+
function parse (string) {
96+
if (typeof string !== 'string') {
97+
return undefined
98+
}
99+
100+
// parse header
101+
var match = CREDENTIALS_REGEXP.exec(string)
102+
103+
if (!match) {
104+
return undefined
105+
}
106+
107+
// decode user pass
108+
var userPass = USER_PASS_REGEXP.exec(decodeBase64(match[1]))
109+
110+
if (!userPass) {
111+
return undefined
112+
}
113+
114+
// return credentials object
115+
return new Credentials(userPass[1], userPass[2])
116+
}
117+
100118
/**
101119
* Object to represent user credentials.
102120
* @private

test/basic-auth.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,3 +117,69 @@ describe('auth(req)', function () {
117117
})
118118
})
119119
})
120+
121+
describe('auth.parse(string)', function () {
122+
describe('with undefined string', function () {
123+
it('should return undefined', function () {
124+
assert.strictEqual(auth.parse(), undefined)
125+
})
126+
})
127+
128+
describe('with malformed string', function () {
129+
it('should return undefined', function () {
130+
assert.strictEqual(auth.parse('Something'), undefined)
131+
})
132+
})
133+
134+
describe('with malformed scheme', function () {
135+
it('should return undefined', function () {
136+
assert.strictEqual(auth.parse('basic_Zm9vOmJhcg=='), undefined)
137+
})
138+
})
139+
140+
describe('with malformed credentials', function () {
141+
it('should return undefined', function () {
142+
assert.strictEqual(auth.parse('basic Zm9vcgo='), undefined)
143+
})
144+
})
145+
146+
describe('with valid credentials', function () {
147+
it('should return .name and .pass', function () {
148+
var creds = auth.parse('basic Zm9vOmJhcg==')
149+
assert.equal(creds.name, 'foo')
150+
assert.equal(creds.pass, 'bar')
151+
})
152+
})
153+
154+
describe('with empty password', function () {
155+
it('should return .name and .pass', function () {
156+
var creds = auth.parse('basic Zm9vOg==')
157+
assert.equal(creds.name, 'foo')
158+
assert.equal(creds.pass, '')
159+
})
160+
})
161+
162+
describe('with empty userid', function () {
163+
it('should return .name and .pass', function () {
164+
var creds = auth.parse('basic OnBhc3M=')
165+
assert.equal(creds.name, '')
166+
assert.equal(creds.pass, 'pass')
167+
})
168+
})
169+
170+
describe('with empty userid and pass', function () {
171+
it('should return .name and .pass', function () {
172+
var creds = auth.parse('basic Og==')
173+
assert.equal(creds.name, '')
174+
assert.equal(creds.pass, '')
175+
})
176+
})
177+
178+
describe('with colon in pass', function () {
179+
it('should return .name and .pass', function () {
180+
var creds = auth.parse('basic Zm9vOnBhc3M6d29yZA==')
181+
assert.equal(creds.name, 'foo')
182+
assert.equal(creds.pass, 'pass:word')
183+
})
184+
})
185+
})

0 commit comments

Comments
 (0)