diff --git a/package.json b/package.json index dde152b..e18a931 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "dist/" ], "scripts": { + "bench": "vitest bench", "build": "ts-scripts build", "format": "ts-scripts format", "lint": "ts-scripts lint", diff --git a/src/index.ts b/src/index.ts index 6576a46..7132042 100644 --- a/src/index.ts +++ b/src/index.ts @@ -31,20 +31,17 @@ export function parse(string: string): Credentials | undefined { // parse header const match = CREDENTIALS_REGEXP.exec(string); - - if (!match) { - return undefined; - } + if (!match) return undefined; // decode user pass - const userPass = USER_PASS_REGEXP.exec(decodeBase64(match[1])); - - if (!userPass) { - return undefined; - } - - // return credentials object - return new CredentialsImpl(userPass[1], userPass[2]); + const userPass = decodeBase64(match[1]); + const colonIndex = userPass.indexOf(':'); + if (colonIndex === -1) return undefined; + + return { + name: userPass.slice(0, colonIndex), + pass: userPass.slice(colonIndex + 1), + }; } /** @@ -59,17 +56,6 @@ export function parse(string: string): Credentials | undefined { const CREDENTIALS_REGEXP = /^ *(?:[Bb][Aa][Ss][Ii][Cc]) +([A-Za-z0-9._~+/-]+=*) *$/; -/** - * RegExp for basic auth user/pass - * - * user-pass = userid ":" password - * userid = * - * password = *TEXT - * @private - */ - -const USER_PASS_REGEXP = /^([^:]*):(.*)$/; - /** * Decode base64 string. * @private @@ -78,13 +64,3 @@ const USER_PASS_REGEXP = /^([^:]*):(.*)$/; function decodeBase64(str: string): string { return Buffer.from(str, 'base64').toString(); } - -class CredentialsImpl implements Credentials { - name: string; - pass: string; - - constructor(name: string, pass: string) { - this.name = name; - this.pass = pass; - } -} diff --git a/src/parse.bench.ts b/src/parse.bench.ts new file mode 100644 index 0000000..e268573 --- /dev/null +++ b/src/parse.bench.ts @@ -0,0 +1,24 @@ +import { describe, bench } from 'vitest'; +import { parse } from './index'; + +describe('parse', () => { + bench('basic auth header', () => { + const header = 'Basic dGVzdDpwYXNzd29yZA=='; // "test:password" in base64 + parse(header); + }); + + bench('basic auth header with extra whitespace', () => { + const header = ' Basic dGVzdDpwYXNzd29yZA== '; // "test:password" in base64 with extra whitespace + parse(header); + }); + + bench('invalid basic auth header', () => { + const header = 'Basic invalidbase64'; // Invalid base64 string + parse(header); + }); + + bench('non-basic auth header', () => { + const header = 'Bearer sometoken'; // Not a basic auth header + parse(header); + }); +});