mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-06 00:07:44 +01:00
6673d131fe
This commit changes our linter/formatter to biome (https://biomejs.dev/) Causing our prehook to run almost instantly, and our "yarn lint" task to run in sub 100ms. Some trade-offs: * Biome isn't quite as well established as ESLint * Are we ready to install a different vscode plugin (the biome plugin) instead of the prettier plugin The configuration set for biome also has a set of recommended rules, this is turned on by default, in order to get to something that was mergeable I have turned off a couple the rules we seemed to violate the most, that we also explicitly told eslint to ignore.
289 lines
8.8 KiB
TypeScript
289 lines
8.8 KiB
TypeScript
import supertest from 'supertest';
|
|
import express from 'express';
|
|
import { createTestConfig } from '../../test/config/test-config';
|
|
|
|
import LogoutController from './logout';
|
|
import { IAuthRequest } from './unleash-types';
|
|
import SessionService from '../services/session-service';
|
|
import FakeSessionStore from '../../test/fixtures/fake-session-store';
|
|
import noLogger from '../../test/fixtures/no-logger';
|
|
import { addDays } from 'date-fns';
|
|
|
|
test('should redirect to "/" after logout', async () => {
|
|
const baseUriPath = '';
|
|
const app = express();
|
|
const config = createTestConfig({ server: { baseUriPath } });
|
|
const sessionStore = new FakeSessionStore();
|
|
const sessionService = new SessionService(
|
|
{ sessionStore },
|
|
{ getLogger: noLogger },
|
|
);
|
|
app.use(
|
|
'/logout',
|
|
new LogoutController(config, {
|
|
sessionService,
|
|
}).router,
|
|
);
|
|
const request = supertest(app);
|
|
expect.assertions(0);
|
|
await request
|
|
.post(`${baseUriPath}/logout`)
|
|
.expect(302)
|
|
.expect('Location', `${baseUriPath}/`);
|
|
});
|
|
|
|
test('should redirect to "/basePath" after logout when baseUriPath is set', async () => {
|
|
const baseUriPath = '/basePath';
|
|
const app = express();
|
|
const config = createTestConfig({ server: { baseUriPath } });
|
|
const sessionStore = new FakeSessionStore();
|
|
const sessionService = new SessionService(
|
|
{ sessionStore },
|
|
{ getLogger: noLogger },
|
|
);
|
|
app.use('/logout', new LogoutController(config, { sessionService }).router);
|
|
const request = supertest(app);
|
|
expect.assertions(0);
|
|
await request
|
|
.post('/logout')
|
|
.expect(302)
|
|
.expect('Location', `${baseUriPath}/`);
|
|
});
|
|
|
|
test('should set "Clear-Site-Data" header', async () => {
|
|
const baseUriPath = '';
|
|
const app = express();
|
|
const config = createTestConfig({ server: { baseUriPath } });
|
|
const sessionStore = new FakeSessionStore();
|
|
const sessionService = new SessionService(
|
|
{ sessionStore },
|
|
{ getLogger: noLogger },
|
|
);
|
|
|
|
app.use('/logout', new LogoutController(config, { sessionService }).router);
|
|
const request = supertest(app);
|
|
expect.assertions(0);
|
|
await request
|
|
.post(`${baseUriPath}/logout`)
|
|
.expect(302)
|
|
.expect('Clear-Site-Data', '"cookies", "storage"');
|
|
});
|
|
|
|
test('should not set "Clear-Site-Data" header', async () => {
|
|
const baseUriPath = '';
|
|
const app = express();
|
|
const config = createTestConfig({
|
|
server: { baseUriPath },
|
|
session: { clearSiteDataOnLogout: false },
|
|
});
|
|
const sessionStore = new FakeSessionStore();
|
|
const sessionService = new SessionService(
|
|
{ sessionStore },
|
|
{ getLogger: noLogger },
|
|
);
|
|
|
|
app.use('/logout', new LogoutController(config, { sessionService }).router);
|
|
const request = supertest(app);
|
|
expect.assertions(1);
|
|
await request
|
|
.post(`${baseUriPath}/logout`)
|
|
.expect(302)
|
|
.expect((res) =>
|
|
expect(res.headers['Clear-Site-Data']).toBeUndefined(),
|
|
);
|
|
});
|
|
|
|
test('should clear "unleash-session" cookies', async () => {
|
|
const baseUriPath = '';
|
|
const app = express();
|
|
const config = createTestConfig({ server: { baseUriPath } });
|
|
const sessionStore = new FakeSessionStore();
|
|
const sessionService = new SessionService(
|
|
{ sessionStore },
|
|
{ getLogger: noLogger },
|
|
);
|
|
|
|
app.use('/logout', new LogoutController(config, { sessionService }).router);
|
|
|
|
const request = supertest(app);
|
|
expect.assertions(0);
|
|
await request
|
|
.post(`${baseUriPath}/logout`)
|
|
.expect(302)
|
|
.expect(
|
|
'Set-Cookie',
|
|
'unleash-session=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT',
|
|
);
|
|
});
|
|
|
|
test('should clear "unleash-session" cookie even when disabled clear site data', async () => {
|
|
const baseUriPath = '';
|
|
const app = express();
|
|
const config = createTestConfig({
|
|
server: { baseUriPath },
|
|
session: { clearSiteDataOnLogout: false },
|
|
});
|
|
const sessionStore = new FakeSessionStore();
|
|
const sessionService = new SessionService(
|
|
{ sessionStore },
|
|
{ getLogger: noLogger },
|
|
);
|
|
|
|
app.use('/logout', new LogoutController(config, { sessionService }).router);
|
|
|
|
const request = supertest(app);
|
|
expect.assertions(0);
|
|
await request
|
|
.post(`${baseUriPath}/logout`)
|
|
.expect(302)
|
|
.expect(
|
|
'Set-Cookie',
|
|
'unleash-session=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT',
|
|
);
|
|
});
|
|
|
|
test('should call destroy on session', async () => {
|
|
const baseUriPath = '';
|
|
const fakeSession = {
|
|
destroy: jest.fn(),
|
|
};
|
|
const app = express();
|
|
const config = createTestConfig({ server: { baseUriPath } });
|
|
app.use((req: IAuthRequest, res, next) => {
|
|
req.session = fakeSession;
|
|
next();
|
|
});
|
|
const sessionStore = new FakeSessionStore();
|
|
const sessionService = new SessionService(
|
|
{ sessionStore },
|
|
{ getLogger: noLogger },
|
|
);
|
|
|
|
app.use('/logout', new LogoutController(config, { sessionService }).router);
|
|
|
|
const request = supertest(app);
|
|
await request.post(`${baseUriPath}/logout`);
|
|
|
|
expect(fakeSession.destroy.mock.calls.length).toBe(1);
|
|
});
|
|
|
|
test('should handle req.logout with callback function', async () => {
|
|
// passport >=0.6.0
|
|
const baseUriPath = '';
|
|
const logoutFunction = jest.fn((cb: (err?: any) => void) => cb());
|
|
const app = express();
|
|
const config = createTestConfig({ server: { baseUriPath } });
|
|
app.use((req: IAuthRequest, res, next) => {
|
|
req.logout = logoutFunction;
|
|
next();
|
|
});
|
|
const sessionStore = new FakeSessionStore();
|
|
const sessionService = new SessionService(
|
|
{ sessionStore },
|
|
{ getLogger: noLogger },
|
|
);
|
|
|
|
app.use('/logout', new LogoutController(config, { sessionService }).router);
|
|
|
|
const request = supertest(app);
|
|
await request.post(`${baseUriPath}/logout`);
|
|
|
|
expect(logoutFunction).toHaveBeenCalledTimes(1);
|
|
expect(logoutFunction).toHaveBeenCalledWith(expect.anything());
|
|
});
|
|
|
|
test('should handle req.logout without callback function', async () => {
|
|
// passport <0.6.0
|
|
const baseUriPath = '';
|
|
const logoutFunction = jest.fn();
|
|
const app = express();
|
|
const config = createTestConfig({ server: { baseUriPath } });
|
|
app.use((req: IAuthRequest, res, next) => {
|
|
req.logout = logoutFunction;
|
|
next();
|
|
});
|
|
const sessionStore = new FakeSessionStore();
|
|
const sessionService = new SessionService(
|
|
{ sessionStore },
|
|
{ getLogger: noLogger },
|
|
);
|
|
|
|
app.use('/logout', new LogoutController(config, { sessionService }).router);
|
|
|
|
const request = supertest(app);
|
|
await request.post(`${baseUriPath}/logout`);
|
|
|
|
expect(logoutFunction).toHaveBeenCalledTimes(1);
|
|
expect(logoutFunction).toHaveBeenCalledWith();
|
|
});
|
|
|
|
test('should redirect to alternative logoutUrl', async () => {
|
|
const fakeSession = {
|
|
destroy: jest.fn(),
|
|
logoutUrl: '/some-other-path',
|
|
};
|
|
const app = express();
|
|
const config = createTestConfig();
|
|
app.use((req: IAuthRequest, res, next) => {
|
|
req.session = fakeSession;
|
|
next();
|
|
});
|
|
const sessionStore = new FakeSessionStore();
|
|
const sessionService = new SessionService(
|
|
{ sessionStore },
|
|
{ getLogger: noLogger },
|
|
);
|
|
|
|
app.use('/logout', new LogoutController(config, { sessionService }).router);
|
|
|
|
const request = supertest(app);
|
|
await request
|
|
.post('/logout')
|
|
.expect(302)
|
|
.expect('Location', '/some-other-path');
|
|
});
|
|
|
|
test('Should destroy sessions for user', async () => {
|
|
const app = express();
|
|
const config = createTestConfig();
|
|
const fakeSession = {
|
|
destroy: jest.fn(),
|
|
user: {
|
|
id: 1,
|
|
},
|
|
};
|
|
app.use((req: IAuthRequest, res, next) => {
|
|
req.session = fakeSession;
|
|
next();
|
|
});
|
|
const sessionStore = new FakeSessionStore();
|
|
const sessionService = new SessionService(
|
|
{ sessionStore },
|
|
{ getLogger: noLogger },
|
|
);
|
|
await sessionStore.insertSession({
|
|
sid: '1',
|
|
sess: {
|
|
user: {
|
|
id: 1,
|
|
},
|
|
},
|
|
expired: addDays(new Date(), 2),
|
|
});
|
|
await sessionStore.insertSession({
|
|
sid: '2',
|
|
sess: {
|
|
user: {
|
|
id: 1,
|
|
},
|
|
},
|
|
expired: addDays(new Date(), 2),
|
|
});
|
|
const activeSessionsBeforeLogout = await sessionStore.getSessionsForUser(1);
|
|
expect(activeSessionsBeforeLogout).toHaveLength(2);
|
|
app.use('/logout', new LogoutController(config, { sessionService }).router);
|
|
await supertest(app).post('/logout').expect(302);
|
|
const activeSessions = await sessionStore.getSessionsForUser(1);
|
|
expect(activeSessions).toHaveLength(0);
|
|
});
|