import http from 'http'; import gateway from '../../lib/Gateway'; import authority from '../../lib/Authority'; import blacklist from '../../lib/Blacklist'; interface Response { body: string status?: number location?: string } function get ( url: string, token?: string, mode = 0 ): Promise { const headers: http.OutgoingHttpHeaders = {}; if (mode === 1) headers.cookie = `cookie_jar=${token}`; else if (mode === 0 && typeof token === 'string') headers.authorization = `Bearer ${token}`; else if (mode === 2) headers.authorization = `Basic ${token}`; return new Promise ((resolve) => { http.get (url, { headers }, (res) => { let body = ''; res.on ('data', (d) => { body += d; }); res.on ('end', () => { resolve ({ body, status: res.statusCode, location: res.headers.location }); }); }); }); } // eslint-disable-next-line max-lines-per-function describe ('gateway', () => { let server: http.Server|null = null; beforeAll (() => { jasmine.clock () .install (); jasmine.clock () .mockDate (new Date); const g = gateway ({ redirect_url: 'http://localhost/auth', cookie_name: 'cookie_jar' }); server = http.createServer ((req, res) => { const passed_handler = () => { res.writeHead (200); res.end ('passed'); }; g (req, res, passed_handler); }); server.listen (3000); }); afterAll (() => { if (server === null) throw new Error ('server is null'); server.close (); jasmine.clock () .tick (24 * 60 * 60 * 1000); jasmine.clock () .uninstall (); }); it ('should redirect any unauthorized request', async () => { const resp = await get ('http://localhost:3000'); expect (resp.status) .toEqual (302); expect (resp.location) .toEqual ('http://localhost/auth'); }); it ('should allow a valid access token', async () => { const token = authority.sign ('access_token', 60); const resp = await get ('http://localhost:3000', token.signature); expect (resp.status) .toEqual (200); expect (resp.body) .toEqual ('passed'); }); it ('should allow a valid access token using cookies', async () => { const token = authority.sign ('access_token', 60); const resp = await get ('http://localhost:3000', token.signature, 1); expect (resp.status) .toEqual (200); expect (resp.body) .toEqual ('passed'); }); it ('should reject an outdated access token', async () => { const token = authority.sign ('access_token', 60); jasmine.clock () .tick (70000); const resp = await get ('http://localhost:3000', token.signature); expect (resp.status) .toEqual (302); expect (resp.location) .toEqual ('http://localhost/auth'); }); it ('should reject a blacklisted access token', async () => { const token = authority.sign ('access_token', 60); blacklist.add_signature (token.id); const resp = await get ('http://localhost:3000', token.signature); expect (resp.status) .toEqual (302); expect (resp.location) .toEqual ('http://localhost/auth'); }); it ('should reject any refresh_token', async () => { const token = authority.sign ('refresh_token', 60); const resp = await get ('http://localhost:3000', token.signature); expect (resp.status) .toEqual (302); expect (resp.location) .toEqual ('http://localhost/auth'); }); it ('should reject any part_token', async () => { const token = authority.sign ('part_token', 60); const resp = await get ('http://localhost:3000', token.signature); expect (resp.status) .toEqual (302); expect (resp.location) .toEqual ('http://localhost/auth'); }); it ('should reject any noname token', async () => { const token = authority.sign ('none', 60); const resp = await get ('http://localhost:3000', token.signature); expect (resp.status) .toEqual (302); expect (resp.location) .toEqual ('http://localhost/auth'); }); it ('should reject non-bearer auth', async () => { const resp = await get ('http://localhost:3000', 'foo:bar', 2); expect (resp.status) .toEqual (302); expect (resp.location) .toEqual ('http://localhost/auth'); }); });