From 6e2377570aa03503b35566ae31c03748bacd30a7 Mon Sep 17 00:00:00 2001 From: Blake Embrey Date: Fri, 31 Jul 2026 09:56:51 -0700 Subject: [PATCH] Simplify format checks --- src/format.spec.ts | 29 ++++++++++------------------- src/index.ts | 28 +++++++++++----------------- 2 files changed, 21 insertions(+), 36 deletions(-) diff --git a/src/format.spec.ts b/src/format.spec.ts index a613e76..88721c3 100644 --- a/src/format.spec.ts +++ b/src/format.spec.ts @@ -5,10 +5,7 @@ describe('format(credentials)', function () { describe('arguments', function () { describe('credentials', function () { it('should be required', function () { - assert.throws( - () => (format as any)(), - /argument credentials is required/, - ); + assert.throws(() => (format as any)(), /credentials is required/); }); it('should accept credentials', function () { @@ -19,63 +16,57 @@ describe('format(credentials)', function () { it('should reject null', function () { assert.throws( format.bind(null, null as any), - /argument credentials is required/, + /credentials is required/, ); }); it('should reject a number', function () { - assert.throws( - format.bind(null, 42 as any), - /argument credentials is required/, - ); + assert.throws(format.bind(null, 42 as any), /credentials is required/); }); it('should reject a string', function () { - assert.throws( - format.bind(null, '' as any), - /argument credentials is required/, - ); + assert.throws(format.bind(null, '' as any), /credentials is required/); }); it('should reject an object without name', function () { assert.throws( format.bind(null, { pass: 'bar' } as any), - /argument credentials is required to have name and pass properties/, + /credentials is required to have name and pass properties/, ); }); it('should reject an object without pass', function () { assert.throws( format.bind(null, { name: 'foo' } as any), - /argument credentials is required to have name and pass properties/, + /credentials is required to have name and pass properties/, ); }); it('should reject an object with non-string name', function () { assert.throws( format.bind(null, { name: 42, pass: 'bar' } as any), - /argument credentials is required to have name and pass properties/, + /credentials is required to have name and pass properties/, ); }); it('should reject an object with non-string pass', function () { assert.throws( format.bind(null, { name: 'foo', pass: 42 } as any), - /argument credentials is required to have name and pass properties/, + /credentials is required to have name and pass properties/, ); }); it('should reject userid containing colon', function () { assert.throws( format.bind(null, { name: 'foo:bar', pass: 'baz' }), - /must not contain a colon or control characters/, + /must not contain a colon/, ); }); it('should reject control chars in userid', function () { assert.throws( format.bind(null, { name: 'foo\u0000bar', pass: 'baz' }), - /must not contain a colon or control characters/, + /must not contain control characters/, ); }); diff --git a/src/index.ts b/src/index.ts index d4d4b1b..6e5a5fd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -52,12 +52,8 @@ export function parse(string: string): Credentials | undefined { * @public */ export function format(credentials: Credentials): string { - if (!credentials) { - throw new TypeError('argument credentials is required'); - } - - if (typeof credentials !== 'object') { - throw new TypeError('argument credentials is required to be an object'); + if (typeof credentials !== 'object' || credentials === null) { + throw new TypeError('credentials is required to be an object'); } if ( @@ -65,26 +61,24 @@ export function format(credentials: Credentials): string { typeof credentials.pass !== 'string' ) { throw new TypeError( - 'argument credentials is required to have name and pass properties', + 'credentials is required to have name and pass properties', ); } - if ( - credentials.name.includes(':') || // RFC 7617 disallows colon in username - CONTROL_CHARS_REGEXP.test(credentials.name) - ) { - throw new TypeError( - 'argument credentials.name must not contain a colon or control characters', - ); + // RFC 7617 disallows colon in username + if (credentials.name.includes(':')) { + throw new TypeError('name must not contain a colon'); } - if (CONTROL_CHARS_REGEXP.test(credentials.pass)) { + const str = credentials.name + ':' + credentials.pass; + + if (CONTROL_CHARS_REGEXP.test(str)) { throw new TypeError( - 'argument credentials.pass must not contain control characters', + 'argument credentials must not contain control characters', ); } - return 'Basic ' + base64.encode(credentials.name + ':' + credentials.pass); + return 'Basic ' + base64.encode(str); } /**