|
|
|
@ -33,18 +33,49 @@ import { HttpConfig, Router } from '.';
|
|
|
|
|
import { loggingServiceMock } from '../logging/logging_service.mock';
|
|
|
|
|
import { HttpServer } from './http_server';
|
|
|
|
|
|
|
|
|
|
const cookieOptions = {
|
|
|
|
|
name: 'sid',
|
|
|
|
|
encryptionKey: 'something_at_least_32_characters',
|
|
|
|
|
validate: () => true,
|
|
|
|
|
isSecure: false,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
interface User {
|
|
|
|
|
id: string;
|
|
|
|
|
roles?: string[];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface StorageData {
|
|
|
|
|
value: User;
|
|
|
|
|
expires: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const chance = new Chance();
|
|
|
|
|
|
|
|
|
|
let server: HttpServer;
|
|
|
|
|
let config: HttpConfig;
|
|
|
|
|
let configWithSSL: HttpConfig;
|
|
|
|
|
|
|
|
|
|
const logger = loggingServiceMock.create();
|
|
|
|
|
|
|
|
|
|
beforeEach(() => {
|
|
|
|
|
config = {
|
|
|
|
|
host: '127.0.0.1',
|
|
|
|
|
maxPayload: new ByteSizeValue(1024),
|
|
|
|
|
port: chance.integer({ min: 10000, max: 15000 }),
|
|
|
|
|
ssl: {},
|
|
|
|
|
ssl: { enabled: false },
|
|
|
|
|
} as HttpConfig;
|
|
|
|
|
|
|
|
|
|
configWithSSL = {
|
|
|
|
|
...config,
|
|
|
|
|
ssl: {
|
|
|
|
|
enabled: true,
|
|
|
|
|
certificate: '/certificate',
|
|
|
|
|
cipherSuites: ['cipherSuite'],
|
|
|
|
|
getSecureOptions: () => 0,
|
|
|
|
|
key: '/key',
|
|
|
|
|
redirectHttpFromPort: config.port + 1,
|
|
|
|
|
},
|
|
|
|
|
} as HttpConfig;
|
|
|
|
|
|
|
|
|
|
server = new HttpServer(logger, 'tests');
|
|
|
|
@ -527,30 +558,14 @@ describe('with `basepath: /bar` and `rewriteBasePath: true`', () => {
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe('with defined `redirectHttpFromPort`', () => {
|
|
|
|
|
let configWithSSL: HttpConfig;
|
|
|
|
|
test('with defined `redirectHttpFromPort`', async () => {
|
|
|
|
|
const router = new Router('/');
|
|
|
|
|
router.get({ path: '/', validate: false }, (req, res) => res.ok({ key: 'value:/' }));
|
|
|
|
|
|
|
|
|
|
beforeEach(async () => {
|
|
|
|
|
configWithSSL = {
|
|
|
|
|
...config,
|
|
|
|
|
ssl: {
|
|
|
|
|
certificate: '/certificate',
|
|
|
|
|
cipherSuites: ['cipherSuite'],
|
|
|
|
|
enabled: true,
|
|
|
|
|
getSecureOptions: () => 0,
|
|
|
|
|
key: '/key',
|
|
|
|
|
redirectHttpFromPort: config.port + 1,
|
|
|
|
|
},
|
|
|
|
|
} as HttpConfig;
|
|
|
|
|
const { registerRouter } = await server.setup(configWithSSL);
|
|
|
|
|
registerRouter(router);
|
|
|
|
|
|
|
|
|
|
const router = new Router('/');
|
|
|
|
|
router.get({ path: '/', validate: false }, (req, res) => res.ok({ key: 'value:/' }));
|
|
|
|
|
|
|
|
|
|
const { registerRouter } = await server.setup(configWithSSL);
|
|
|
|
|
registerRouter(router);
|
|
|
|
|
|
|
|
|
|
await server.start();
|
|
|
|
|
});
|
|
|
|
|
await server.start();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('returns server and connection options on start', async () => {
|
|
|
|
@ -578,205 +593,6 @@ test('throws an error if starts without set up', async () => {
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const cookieOptions = {
|
|
|
|
|
name: 'sid',
|
|
|
|
|
encryptionKey: 'something_at_least_32_characters',
|
|
|
|
|
validate: () => true,
|
|
|
|
|
isSecure: false,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
interface User {
|
|
|
|
|
id: string;
|
|
|
|
|
roles?: string[];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface StorageData {
|
|
|
|
|
value: User;
|
|
|
|
|
expires: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
describe('#registerAuth', () => {
|
|
|
|
|
it('registers auth request interceptor only once', async () => {
|
|
|
|
|
const { registerAuth } = await server.setup(config);
|
|
|
|
|
const doRegister = () =>
|
|
|
|
|
registerAuth(() => null as any, {
|
|
|
|
|
encryptionKey: 'any_password',
|
|
|
|
|
} as any);
|
|
|
|
|
|
|
|
|
|
await doRegister();
|
|
|
|
|
expect(doRegister()).rejects.toThrowError('Auth interceptor was already registered');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('supports implementing custom authentication logic', async () => {
|
|
|
|
|
const router = new Router('');
|
|
|
|
|
router.get({ path: '/', validate: false }, async (req, res) => res.ok({ content: 'ok' }));
|
|
|
|
|
|
|
|
|
|
const { registerAuth, registerRouter, server: innerServer } = await server.setup(config);
|
|
|
|
|
const { sessionStorageFactory } = await registerAuth<StorageData>((req, t) => {
|
|
|
|
|
const user = { id: '42' };
|
|
|
|
|
const sessionStorage = sessionStorageFactory.asScoped(req);
|
|
|
|
|
sessionStorage.set({ value: user, expires: Date.now() + 1000 });
|
|
|
|
|
return t.authenticated({ state: user });
|
|
|
|
|
}, cookieOptions);
|
|
|
|
|
registerRouter(router);
|
|
|
|
|
await server.start();
|
|
|
|
|
|
|
|
|
|
const response = await supertest(innerServer.listener)
|
|
|
|
|
.get('/')
|
|
|
|
|
.expect(200, { content: 'ok' });
|
|
|
|
|
|
|
|
|
|
expect(response.header['set-cookie']).toBeDefined();
|
|
|
|
|
const cookies = response.header['set-cookie'];
|
|
|
|
|
expect(cookies).toHaveLength(1);
|
|
|
|
|
|
|
|
|
|
const sessionCookie = request.cookie(cookies[0]);
|
|
|
|
|
if (!sessionCookie) {
|
|
|
|
|
throw new Error('session cookie expected to be defined');
|
|
|
|
|
}
|
|
|
|
|
expect(sessionCookie).toBeDefined();
|
|
|
|
|
expect(sessionCookie.key).toBe('sid');
|
|
|
|
|
expect(sessionCookie.value).toBeDefined();
|
|
|
|
|
expect(sessionCookie.path).toBe('/');
|
|
|
|
|
expect(sessionCookie.httpOnly).toBe(true);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('supports rejecting a request from an unauthenticated user', async () => {
|
|
|
|
|
const { registerAuth, registerRouter, server: innerServer } = await server.setup(config);
|
|
|
|
|
const router = new Router('');
|
|
|
|
|
router.get({ path: '/', validate: false }, async (req, res) => res.ok({ content: 'ok' }));
|
|
|
|
|
registerRouter(router);
|
|
|
|
|
|
|
|
|
|
await registerAuth((req, t) => t.rejected(Boom.unauthorized()), cookieOptions);
|
|
|
|
|
await server.start();
|
|
|
|
|
|
|
|
|
|
await supertest(innerServer.listener)
|
|
|
|
|
.get('/')
|
|
|
|
|
.expect(401);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('supports redirecting', async () => {
|
|
|
|
|
const redirectTo = '/redirect-url';
|
|
|
|
|
const { registerAuth, registerRouter, server: innerServer } = await server.setup(config);
|
|
|
|
|
const router = new Router('');
|
|
|
|
|
router.get({ path: '/', validate: false }, async (req, res) => res.ok({ content: 'ok' }));
|
|
|
|
|
registerRouter(router);
|
|
|
|
|
|
|
|
|
|
await registerAuth((req, t) => {
|
|
|
|
|
return t.redirected(redirectTo);
|
|
|
|
|
}, cookieOptions);
|
|
|
|
|
await server.start();
|
|
|
|
|
|
|
|
|
|
const response = await supertest(innerServer.listener)
|
|
|
|
|
.get('/')
|
|
|
|
|
.expect(302);
|
|
|
|
|
expect(response.header.location).toBe(redirectTo);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it(`doesn't expose internal error details`, async () => {
|
|
|
|
|
const { registerAuth, registerRouter, server: innerServer } = await server.setup(config);
|
|
|
|
|
const router = new Router('');
|
|
|
|
|
router.get({ path: '/', validate: false }, async (req, res) => res.ok({ content: 'ok' }));
|
|
|
|
|
registerRouter(router);
|
|
|
|
|
|
|
|
|
|
await registerAuth((req, t) => {
|
|
|
|
|
throw new Error('sensitive info');
|
|
|
|
|
}, cookieOptions);
|
|
|
|
|
await server.start();
|
|
|
|
|
|
|
|
|
|
await supertest(innerServer.listener)
|
|
|
|
|
.get('/')
|
|
|
|
|
.expect({
|
|
|
|
|
statusCode: 500,
|
|
|
|
|
error: 'Internal Server Error',
|
|
|
|
|
message: 'An internal server error occurred',
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('allows manipulating cookies from route handler', async () => {
|
|
|
|
|
const { registerAuth, registerRouter, server: innerServer } = await server.setup(config);
|
|
|
|
|
const { sessionStorageFactory } = await registerAuth<StorageData>((req, t) => {
|
|
|
|
|
const user = { id: '42' };
|
|
|
|
|
const sessionStorage = sessionStorageFactory.asScoped(req);
|
|
|
|
|
sessionStorage.set({ value: user, expires: Date.now() + 1000 });
|
|
|
|
|
return t.authenticated();
|
|
|
|
|
}, cookieOptions);
|
|
|
|
|
|
|
|
|
|
const router = new Router('');
|
|
|
|
|
router.get({ path: '/', validate: false }, (req, res) => res.ok({ content: 'ok' }));
|
|
|
|
|
router.get({ path: '/with-cookie', validate: false }, (req, res) => {
|
|
|
|
|
const sessionStorage = sessionStorageFactory.asScoped(req);
|
|
|
|
|
sessionStorage.clear();
|
|
|
|
|
return res.ok({ content: 'ok' });
|
|
|
|
|
});
|
|
|
|
|
registerRouter(router);
|
|
|
|
|
|
|
|
|
|
await server.start();
|
|
|
|
|
|
|
|
|
|
const responseToSetCookie = await supertest(innerServer.listener)
|
|
|
|
|
.get('/')
|
|
|
|
|
.expect(200);
|
|
|
|
|
|
|
|
|
|
expect(responseToSetCookie.header['set-cookie']).toBeDefined();
|
|
|
|
|
|
|
|
|
|
const responseToResetCookie = await supertest(innerServer.listener)
|
|
|
|
|
.get('/with-cookie')
|
|
|
|
|
.expect(200);
|
|
|
|
|
|
|
|
|
|
expect(responseToResetCookie.header['set-cookie']).toEqual([
|
|
|
|
|
'sid=; Max-Age=0; Expires=Thu, 01 Jan 1970 00:00:00 GMT; HttpOnly; Path=/',
|
|
|
|
|
]);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it.skip('is the only place with access to the authorization header', async () => {
|
|
|
|
|
const token = 'Basic: user:password';
|
|
|
|
|
const {
|
|
|
|
|
registerAuth,
|
|
|
|
|
registerOnPreAuth,
|
|
|
|
|
registerOnPostAuth,
|
|
|
|
|
registerRouter,
|
|
|
|
|
server: innerServer,
|
|
|
|
|
} = await server.setup(config);
|
|
|
|
|
|
|
|
|
|
let fromRegisterOnPreAuth;
|
|
|
|
|
await registerOnPreAuth((req, t) => {
|
|
|
|
|
fromRegisterOnPreAuth = req.headers.authorization;
|
|
|
|
|
return t.next();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
let fromRegisterAuth;
|
|
|
|
|
await registerAuth((req, t) => {
|
|
|
|
|
fromRegisterAuth = req.headers.authorization;
|
|
|
|
|
return t.authenticated();
|
|
|
|
|
}, cookieOptions);
|
|
|
|
|
|
|
|
|
|
let fromRegisterOnPostAuth;
|
|
|
|
|
await registerOnPostAuth((req, t) => {
|
|
|
|
|
fromRegisterOnPostAuth = req.headers.authorization;
|
|
|
|
|
return t.next();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
let fromRouteHandler;
|
|
|
|
|
const router = new Router('');
|
|
|
|
|
router.get({ path: '/', validate: false }, (req, res) => {
|
|
|
|
|
fromRouteHandler = req.headers.authorization;
|
|
|
|
|
return res.ok({ content: 'ok' });
|
|
|
|
|
});
|
|
|
|
|
registerRouter(router);
|
|
|
|
|
|
|
|
|
|
await server.start();
|
|
|
|
|
|
|
|
|
|
await supertest(innerServer.listener)
|
|
|
|
|
.get('/')
|
|
|
|
|
.set('Authorization', token)
|
|
|
|
|
.expect(200);
|
|
|
|
|
|
|
|
|
|
expect(fromRegisterOnPreAuth).toEqual({});
|
|
|
|
|
expect(fromRegisterAuth).toEqual({ authorization: token });
|
|
|
|
|
expect(fromRegisterOnPostAuth).toEqual({});
|
|
|
|
|
expect(fromRouteHandler).toEqual({});
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('enables auth for a route by default if registerAuth has been called', async () => {
|
|
|
|
|
const { registerAuth, registerRouter, server: innerServer } = await server.setup(config);
|
|
|
|
|
|
|
|
|
@ -878,105 +694,308 @@ test('exposes route details of incoming request to a route handler', async () =>
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe('#auth.isAuthenticated()', () => {
|
|
|
|
|
it('returns true if has been authorized', async () => {
|
|
|
|
|
const { registerAuth, registerRouter, server: innerServer, auth } = await server.setup(config);
|
|
|
|
|
describe('setup contract', () => {
|
|
|
|
|
describe('#registerAuth', () => {
|
|
|
|
|
it('registers auth request interceptor only once', async () => {
|
|
|
|
|
const { registerAuth } = await server.setup(config);
|
|
|
|
|
const doRegister = () =>
|
|
|
|
|
registerAuth(() => null as any, {
|
|
|
|
|
encryptionKey: 'any_password',
|
|
|
|
|
} as any);
|
|
|
|
|
|
|
|
|
|
const router = new Router('');
|
|
|
|
|
router.get({ path: '/', validate: false }, (req, res) =>
|
|
|
|
|
res.ok({ isAuthenticated: auth.isAuthenticated(req) })
|
|
|
|
|
);
|
|
|
|
|
registerRouter(router);
|
|
|
|
|
await doRegister();
|
|
|
|
|
expect(doRegister()).rejects.toThrowError('Auth interceptor was already registered');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
await registerAuth((req, t) => t.authenticated(), cookieOptions);
|
|
|
|
|
it('supports implementing custom authentication logic', async () => {
|
|
|
|
|
const router = new Router('');
|
|
|
|
|
router.get({ path: '/', validate: false }, async (req, res) => res.ok({ content: 'ok' }));
|
|
|
|
|
|
|
|
|
|
await server.start();
|
|
|
|
|
await supertest(innerServer.listener)
|
|
|
|
|
.get('/')
|
|
|
|
|
.expect(200, { isAuthenticated: true });
|
|
|
|
|
const { registerAuth, registerRouter, server: innerServer } = await server.setup(config);
|
|
|
|
|
const { sessionStorageFactory } = await registerAuth<StorageData>((req, t) => {
|
|
|
|
|
const user = { id: '42' };
|
|
|
|
|
const sessionStorage = sessionStorageFactory.asScoped(req);
|
|
|
|
|
sessionStorage.set({ value: user, expires: Date.now() + 1000 });
|
|
|
|
|
return t.authenticated({ state: user });
|
|
|
|
|
}, cookieOptions);
|
|
|
|
|
registerRouter(router);
|
|
|
|
|
await server.start();
|
|
|
|
|
|
|
|
|
|
const response = await supertest(innerServer.listener)
|
|
|
|
|
.get('/')
|
|
|
|
|
.expect(200, { content: 'ok' });
|
|
|
|
|
|
|
|
|
|
expect(response.header['set-cookie']).toBeDefined();
|
|
|
|
|
const cookies = response.header['set-cookie'];
|
|
|
|
|
expect(cookies).toHaveLength(1);
|
|
|
|
|
|
|
|
|
|
const sessionCookie = request.cookie(cookies[0]);
|
|
|
|
|
if (!sessionCookie) {
|
|
|
|
|
throw new Error('session cookie expected to be defined');
|
|
|
|
|
}
|
|
|
|
|
expect(sessionCookie).toBeDefined();
|
|
|
|
|
expect(sessionCookie.key).toBe('sid');
|
|
|
|
|
expect(sessionCookie.value).toBeDefined();
|
|
|
|
|
expect(sessionCookie.path).toBe('/');
|
|
|
|
|
expect(sessionCookie.httpOnly).toBe(true);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('supports rejecting a request from an unauthenticated user', async () => {
|
|
|
|
|
const { registerAuth, registerRouter, server: innerServer } = await server.setup(config);
|
|
|
|
|
const router = new Router('');
|
|
|
|
|
router.get({ path: '/', validate: false }, async (req, res) => res.ok({ content: 'ok' }));
|
|
|
|
|
registerRouter(router);
|
|
|
|
|
|
|
|
|
|
await registerAuth((req, t) => t.rejected(Boom.unauthorized()), cookieOptions);
|
|
|
|
|
await server.start();
|
|
|
|
|
|
|
|
|
|
await supertest(innerServer.listener)
|
|
|
|
|
.get('/')
|
|
|
|
|
.expect(401);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('supports redirecting', async () => {
|
|
|
|
|
const redirectTo = '/redirect-url';
|
|
|
|
|
const { registerAuth, registerRouter, server: innerServer } = await server.setup(config);
|
|
|
|
|
const router = new Router('');
|
|
|
|
|
router.get({ path: '/', validate: false }, async (req, res) => res.ok({ content: 'ok' }));
|
|
|
|
|
registerRouter(router);
|
|
|
|
|
|
|
|
|
|
await registerAuth((req, t) => {
|
|
|
|
|
return t.redirected(redirectTo);
|
|
|
|
|
}, cookieOptions);
|
|
|
|
|
await server.start();
|
|
|
|
|
|
|
|
|
|
const response = await supertest(innerServer.listener)
|
|
|
|
|
.get('/')
|
|
|
|
|
.expect(302);
|
|
|
|
|
expect(response.header.location).toBe(redirectTo);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it(`doesn't expose internal error details`, async () => {
|
|
|
|
|
const { registerAuth, registerRouter, server: innerServer } = await server.setup(config);
|
|
|
|
|
const router = new Router('');
|
|
|
|
|
router.get({ path: '/', validate: false }, async (req, res) => res.ok({ content: 'ok' }));
|
|
|
|
|
registerRouter(router);
|
|
|
|
|
|
|
|
|
|
await registerAuth((req, t) => {
|
|
|
|
|
throw new Error('sensitive info');
|
|
|
|
|
}, cookieOptions);
|
|
|
|
|
await server.start();
|
|
|
|
|
|
|
|
|
|
await supertest(innerServer.listener)
|
|
|
|
|
.get('/')
|
|
|
|
|
.expect({
|
|
|
|
|
statusCode: 500,
|
|
|
|
|
error: 'Internal Server Error',
|
|
|
|
|
message: 'An internal server error occurred',
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('allows manipulating cookies from route handler', async () => {
|
|
|
|
|
const { registerAuth, registerRouter, server: innerServer } = await server.setup(config);
|
|
|
|
|
const { sessionStorageFactory } = await registerAuth<StorageData>((req, t) => {
|
|
|
|
|
const user = { id: '42' };
|
|
|
|
|
const sessionStorage = sessionStorageFactory.asScoped(req);
|
|
|
|
|
sessionStorage.set({ value: user, expires: Date.now() + 1000 });
|
|
|
|
|
return t.authenticated();
|
|
|
|
|
}, cookieOptions);
|
|
|
|
|
|
|
|
|
|
const router = new Router('');
|
|
|
|
|
router.get({ path: '/', validate: false }, (req, res) => res.ok({ content: 'ok' }));
|
|
|
|
|
router.get({ path: '/with-cookie', validate: false }, (req, res) => {
|
|
|
|
|
const sessionStorage = sessionStorageFactory.asScoped(req);
|
|
|
|
|
sessionStorage.clear();
|
|
|
|
|
return res.ok({ content: 'ok' });
|
|
|
|
|
});
|
|
|
|
|
registerRouter(router);
|
|
|
|
|
|
|
|
|
|
await server.start();
|
|
|
|
|
|
|
|
|
|
const responseToSetCookie = await supertest(innerServer.listener)
|
|
|
|
|
.get('/')
|
|
|
|
|
.expect(200);
|
|
|
|
|
|
|
|
|
|
expect(responseToSetCookie.header['set-cookie']).toBeDefined();
|
|
|
|
|
|
|
|
|
|
const responseToResetCookie = await supertest(innerServer.listener)
|
|
|
|
|
.get('/with-cookie')
|
|
|
|
|
.expect(200);
|
|
|
|
|
|
|
|
|
|
expect(responseToResetCookie.header['set-cookie']).toEqual([
|
|
|
|
|
'sid=; Max-Age=0; Expires=Thu, 01 Jan 1970 00:00:00 GMT; HttpOnly; Path=/',
|
|
|
|
|
]);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it.skip('is the only place with access to the authorization header', async () => {
|
|
|
|
|
const token = 'Basic: user:password';
|
|
|
|
|
const {
|
|
|
|
|
registerAuth,
|
|
|
|
|
registerOnPreAuth,
|
|
|
|
|
registerOnPostAuth,
|
|
|
|
|
registerRouter,
|
|
|
|
|
server: innerServer,
|
|
|
|
|
} = await server.setup(config);
|
|
|
|
|
|
|
|
|
|
let fromRegisterOnPreAuth;
|
|
|
|
|
await registerOnPreAuth((req, t) => {
|
|
|
|
|
fromRegisterOnPreAuth = req.headers.authorization;
|
|
|
|
|
return t.next();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
let fromRegisterAuth;
|
|
|
|
|
await registerAuth((req, t) => {
|
|
|
|
|
fromRegisterAuth = req.headers.authorization;
|
|
|
|
|
return t.authenticated();
|
|
|
|
|
}, cookieOptions);
|
|
|
|
|
|
|
|
|
|
let fromRegisterOnPostAuth;
|
|
|
|
|
await registerOnPostAuth((req, t) => {
|
|
|
|
|
fromRegisterOnPostAuth = req.headers.authorization;
|
|
|
|
|
return t.next();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
let fromRouteHandler;
|
|
|
|
|
const router = new Router('');
|
|
|
|
|
router.get({ path: '/', validate: false }, (req, res) => {
|
|
|
|
|
fromRouteHandler = req.headers.authorization;
|
|
|
|
|
return res.ok({ content: 'ok' });
|
|
|
|
|
});
|
|
|
|
|
registerRouter(router);
|
|
|
|
|
|
|
|
|
|
await server.start();
|
|
|
|
|
|
|
|
|
|
await supertest(innerServer.listener)
|
|
|
|
|
.get('/')
|
|
|
|
|
.set('Authorization', token)
|
|
|
|
|
.expect(200);
|
|
|
|
|
|
|
|
|
|
expect(fromRegisterOnPreAuth).toEqual({});
|
|
|
|
|
expect(fromRegisterAuth).toEqual({ authorization: token });
|
|
|
|
|
expect(fromRegisterOnPostAuth).toEqual({});
|
|
|
|
|
expect(fromRouteHandler).toEqual({});
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('returns false if has not been authorized', async () => {
|
|
|
|
|
const { registerAuth, registerRouter, server: innerServer, auth } = await server.setup(config);
|
|
|
|
|
describe('#auth.isAuthenticated()', () => {
|
|
|
|
|
it('returns true if has been authorized', async () => {
|
|
|
|
|
const { registerAuth, registerRouter, server: innerServer, auth } = await server.setup(
|
|
|
|
|
config
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const router = new Router('');
|
|
|
|
|
router.get({ path: '/', validate: false, options: { authRequired: false } }, (req, res) =>
|
|
|
|
|
res.ok({ isAuthenticated: auth.isAuthenticated(req) })
|
|
|
|
|
);
|
|
|
|
|
registerRouter(router);
|
|
|
|
|
const router = new Router('');
|
|
|
|
|
router.get({ path: '/', validate: false }, (req, res) =>
|
|
|
|
|
res.ok({ isAuthenticated: auth.isAuthenticated(req) })
|
|
|
|
|
);
|
|
|
|
|
registerRouter(router);
|
|
|
|
|
|
|
|
|
|
await registerAuth((req, t) => t.authenticated(), cookieOptions);
|
|
|
|
|
await registerAuth((req, t) => t.authenticated(), cookieOptions);
|
|
|
|
|
|
|
|
|
|
await server.start();
|
|
|
|
|
await supertest(innerServer.listener)
|
|
|
|
|
.get('/')
|
|
|
|
|
.expect(200, { isAuthenticated: false });
|
|
|
|
|
await server.start();
|
|
|
|
|
await supertest(innerServer.listener)
|
|
|
|
|
.get('/')
|
|
|
|
|
.expect(200, { isAuthenticated: true });
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('returns false if has not been authorized', async () => {
|
|
|
|
|
const { registerAuth, registerRouter, server: innerServer, auth } = await server.setup(
|
|
|
|
|
config
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const router = new Router('');
|
|
|
|
|
router.get({ path: '/', validate: false, options: { authRequired: false } }, (req, res) =>
|
|
|
|
|
res.ok({ isAuthenticated: auth.isAuthenticated(req) })
|
|
|
|
|
);
|
|
|
|
|
registerRouter(router);
|
|
|
|
|
|
|
|
|
|
await registerAuth((req, t) => t.authenticated(), cookieOptions);
|
|
|
|
|
|
|
|
|
|
await server.start();
|
|
|
|
|
await supertest(innerServer.listener)
|
|
|
|
|
.get('/')
|
|
|
|
|
.expect(200, { isAuthenticated: false });
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('returns false if no authorization mechanism has been registered', async () => {
|
|
|
|
|
const { registerRouter, server: innerServer, auth } = await server.setup(config);
|
|
|
|
|
|
|
|
|
|
const router = new Router('');
|
|
|
|
|
router.get({ path: '/', validate: false, options: { authRequired: false } }, (req, res) =>
|
|
|
|
|
res.ok({ isAuthenticated: auth.isAuthenticated(req) })
|
|
|
|
|
);
|
|
|
|
|
registerRouter(router);
|
|
|
|
|
|
|
|
|
|
await server.start();
|
|
|
|
|
await supertest(innerServer.listener)
|
|
|
|
|
.get('/')
|
|
|
|
|
.expect(200, { isAuthenticated: false });
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('returns false if no authorization mechanism has been registered', async () => {
|
|
|
|
|
const { registerRouter, server: innerServer, auth } = await server.setup(config);
|
|
|
|
|
describe('#auth.get()', () => {
|
|
|
|
|
it('returns authenticated status and allow associate auth state with request', async () => {
|
|
|
|
|
const user = { id: '42' };
|
|
|
|
|
const { registerRouter, registerAuth, server: innerServer, auth } = await server.setup(
|
|
|
|
|
config
|
|
|
|
|
);
|
|
|
|
|
const { sessionStorageFactory } = await registerAuth<StorageData>((req, t) => {
|
|
|
|
|
sessionStorageFactory.asScoped(req).set({ value: user, expires: Date.now() + 1000 });
|
|
|
|
|
return t.authenticated({ state: user });
|
|
|
|
|
}, cookieOptions);
|
|
|
|
|
|
|
|
|
|
const router = new Router('');
|
|
|
|
|
router.get({ path: '/', validate: false, options: { authRequired: false } }, (req, res) =>
|
|
|
|
|
res.ok({ isAuthenticated: auth.isAuthenticated(req) })
|
|
|
|
|
);
|
|
|
|
|
registerRouter(router);
|
|
|
|
|
const router = new Router('');
|
|
|
|
|
router.get({ path: '/', validate: false }, (req, res) => res.ok(auth.get(req)));
|
|
|
|
|
registerRouter(router);
|
|
|
|
|
await server.start();
|
|
|
|
|
|
|
|
|
|
await server.start();
|
|
|
|
|
await supertest(innerServer.listener)
|
|
|
|
|
.get('/')
|
|
|
|
|
.expect(200, { isAuthenticated: false });
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe('#auth.get()', () => {
|
|
|
|
|
it('returns authenticated status and allow associate auth state with request', async () => {
|
|
|
|
|
const user = { id: '42' };
|
|
|
|
|
const { registerRouter, registerAuth, server: innerServer, auth } = await server.setup(config);
|
|
|
|
|
const { sessionStorageFactory } = await registerAuth<StorageData>((req, t) => {
|
|
|
|
|
sessionStorageFactory.asScoped(req).set({ value: user, expires: Date.now() + 1000 });
|
|
|
|
|
return t.authenticated({ state: user });
|
|
|
|
|
}, cookieOptions);
|
|
|
|
|
|
|
|
|
|
const router = new Router('');
|
|
|
|
|
router.get({ path: '/', validate: false }, (req, res) => res.ok(auth.get(req)));
|
|
|
|
|
registerRouter(router);
|
|
|
|
|
await server.start();
|
|
|
|
|
|
|
|
|
|
await supertest(innerServer.listener)
|
|
|
|
|
.get('/')
|
|
|
|
|
.expect(200, { state: user, status: 'authenticated' });
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('returns correct authentication unknown status', async () => {
|
|
|
|
|
const { registerRouter, server: innerServer, auth } = await server.setup(config);
|
|
|
|
|
const router = new Router('');
|
|
|
|
|
router.get({ path: '/', validate: false }, (req, res) => res.ok(auth.get(req)));
|
|
|
|
|
|
|
|
|
|
registerRouter(router);
|
|
|
|
|
await server.start();
|
|
|
|
|
await supertest(innerServer.listener)
|
|
|
|
|
.get('/')
|
|
|
|
|
.expect(200, { status: 'unknown' });
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('returns correct unauthenticated status', async () => {
|
|
|
|
|
const authenticate = jest.fn();
|
|
|
|
|
|
|
|
|
|
const { registerRouter, registerAuth, server: innerServer, auth } = await server.setup(config);
|
|
|
|
|
await registerAuth(authenticate, cookieOptions);
|
|
|
|
|
const router = new Router('');
|
|
|
|
|
router.get({ path: '/', validate: false, options: { authRequired: false } }, (req, res) =>
|
|
|
|
|
res.ok(auth.get(req))
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
registerRouter(router);
|
|
|
|
|
await server.start();
|
|
|
|
|
|
|
|
|
|
await supertest(innerServer.listener)
|
|
|
|
|
.get('/')
|
|
|
|
|
.expect(200, { status: 'unauthenticated' });
|
|
|
|
|
|
|
|
|
|
expect(authenticate).not.toHaveBeenCalled();
|
|
|
|
|
await supertest(innerServer.listener)
|
|
|
|
|
.get('/')
|
|
|
|
|
.expect(200, { state: user, status: 'authenticated' });
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('returns correct authentication unknown status', async () => {
|
|
|
|
|
const { registerRouter, server: innerServer, auth } = await server.setup(config);
|
|
|
|
|
const router = new Router('');
|
|
|
|
|
router.get({ path: '/', validate: false }, (req, res) => res.ok(auth.get(req)));
|
|
|
|
|
|
|
|
|
|
registerRouter(router);
|
|
|
|
|
await server.start();
|
|
|
|
|
await supertest(innerServer.listener)
|
|
|
|
|
.get('/')
|
|
|
|
|
.expect(200, { status: 'unknown' });
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('returns correct unauthenticated status', async () => {
|
|
|
|
|
const authenticate = jest.fn();
|
|
|
|
|
|
|
|
|
|
const { registerRouter, registerAuth, server: innerServer, auth } = await server.setup(
|
|
|
|
|
config
|
|
|
|
|
);
|
|
|
|
|
await registerAuth(authenticate, cookieOptions);
|
|
|
|
|
const router = new Router('');
|
|
|
|
|
router.get({ path: '/', validate: false, options: { authRequired: false } }, (req, res) =>
|
|
|
|
|
res.ok(auth.get(req))
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
registerRouter(router);
|
|
|
|
|
await server.start();
|
|
|
|
|
|
|
|
|
|
await supertest(innerServer.listener)
|
|
|
|
|
.get('/')
|
|
|
|
|
.expect(200, { status: 'unauthenticated' });
|
|
|
|
|
|
|
|
|
|
expect(authenticate).not.toHaveBeenCalled();
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe('#isTlsEnabled', () => {
|
|
|
|
|
it('returns "true" if TLS enabled', async () => {
|
|
|
|
|
const { isTlsEnabled } = await server.setup(configWithSSL);
|
|
|
|
|
expect(isTlsEnabled).toBe(true);
|
|
|
|
|
});
|
|
|
|
|
it('returns "false" if TLS not enabled', async () => {
|
|
|
|
|
const { isTlsEnabled } = await server.setup(config);
|
|
|
|
|
expect(isTlsEnabled).toBe(false);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|