diff --git a/lib/AuthHandler.ts b/lib/AuthHandler.ts index 3f34e30..c46d449 100644 --- a/lib/AuthHandler.ts +++ b/lib/AuthHandler.ts @@ -188,10 +188,8 @@ export default function create_auth_handler ( const token = (/(?\S+) (?.+)/ui) .exec (req.headers.authorization as string); - if (token === null) { - request.invalid ('missing authorization header'); - return Promise.resolve (); - } + if (token === null) + return default_handler (request); if ((/Basic/ui).test (token?.groups?.type as string)) { request.is_basic = true; diff --git a/lib/index.ts b/lib/index.ts index 0b869e4..2d1fa20 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -28,13 +28,14 @@ import create_gateway, { Gateway, AnyFunc } from './Gateway'; -import { KeyStore, KeyStoreData } from './KeyStore'; +import keystore, { KeyStore, KeyStoreData } from './KeyStore'; export { create_gateway, create_auth_handler, blacklist, authority, + keystore, AccessResponse, CreateHandlerOptions, diff --git a/test/spec/AuthHandler.ts b/test/spec/AuthHandler.ts index 2a48e46..2047612 100644 --- a/test/spec/AuthHandler.ts +++ b/test/spec/AuthHandler.ts @@ -57,7 +57,23 @@ describe ('auth handler', () => { const ah = create_auth_handler ((req) => { if (!req.is_basic && !req.is_bearer) { - req.invalid ('unknown authorization type'); + let body_auth = false; + try { + const data = JSON.parse (req.body); + if (data.username === 'foo' && data.password === 'bar') { + req.allow_access ({ + access_token_expires_in: expires_seconds, + include_refresh_token: true, + refresh_token_expires_in: refresh_expires_seconds + }); + body_auth = true; + } + } + catch { + body_auth = false; + } + if (!body_auth) + req.invalid ('unknown authorization type'); } else if (req.is_bearer) { req.deny (); @@ -160,7 +176,6 @@ describe ('auth handler', () => { }); it ('should allow base64 login', async () => { - // get initial access and refresh tokens const resp1 = await get ({ authorization: `Basic ${to_b64 ('foo:bar')}` }); expect (resp1.statusCode) .toEqual (200); @@ -179,6 +194,29 @@ describe ('auth handler', () => { .toEqual (refresh_expires_seconds); }); + it ('should allow body login', async () => { + const resp1 = await get ( + // eslint-disable-next-line @typescript-eslint/naming-convention + { 'Content-Type': 'application/json' }, + JSON.stringify ({ username: 'foo', password: 'bar' }) + ); + expect (resp1.statusCode) + .toEqual (200); + const res1 = check_headers (resp1); + expect (res1.data.token_type) + .toEqual ('bearer'); + expect (resp1.headers['set-cookie']) + .toContain (`cookie_jar=${res1.at}`); + + check_token (res1.at as string, 'access_token'); + expect (res1.data.expires_in) + .toEqual (expires_seconds); + + check_token (res1.rt as string, 'refresh_token'); + expect (res1.data.refresh_expires_in) + .toEqual (refresh_expires_seconds); + }); + it ('should reject invalid requests', async () => { const resp1 = await get (); expect (resp1.statusCode) @@ -187,7 +225,7 @@ describe ('auth handler', () => { expect (res1.data) .toEqual ({ error: 'invalid_request', - error_description: 'missing authorization header' + error_description: 'unknown authorization type' }); const resp2a = await get ({ authorization: 'Basic foo:bar' });