1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-02-23 00:22:19 +01:00

fix: logout-controller should support logoutUrl override (#881)

This commit is contained in:
Ivar Conradi Østhus 2021-07-18 21:42:36 +02:00 committed by GitHub
parent ef8ce8ba23
commit 0ff89ebdf3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 127 additions and 76 deletions

9
public.pem Normal file
View File

@ -0,0 +1,9 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxmXH/2XHkkpsxldCK7bx
cZKf0jgPTRFMXnoZRdPe1n8I8feRTm2SMHUf2DuXoLtueHYn1vT2H/fMZ4E1DXA2
2sxKfKjzXMroKg+jbEtHNkIV2wypE+Jpw3iGrHY9axpFv9M6sD7VSXbeBWrDvMEb
StSdMSaHQfgaCMun3VGwzspZSOkfIO+cENTfvEClh+eans00o3L8aAmUWJjqku04
ZiyrLmIMPV0rrmsukd+D1UDO65Oz4k/bewZNAxrgn06sPvMjjsK6Is5ceppc/zCn
AHWJcmhX9L+x96ZNV068/wypMtYJ8GM9UnBlSlQPRaPQoPoeKd7Y1FNPB66ybvwd
rwIDAQAB
-----END PUBLIC KEY-----

View File

@ -1,24 +0,0 @@
'use strict';
const Controller = require('./controller');
class LogoutController extends Controller {
constructor(config) {
super(config);
this.baseUri = config.server.baseUriPath;
this.get('/', this.logout);
}
logout(req, res) {
if (req.session) {
req.session.destroy();
}
if (req.logout) {
req.logout();
}
res.set('Clear-Site-Data', '"cookies"');
res.redirect(`${this.baseUri}/`);
}
}
module.exports = LogoutController;

View File

@ -1,52 +0,0 @@
'use strict';
const supertest = require('supertest');
const { EventEmitter } = require('events');
const { createServices } = require('../services');
const { createTestConfig } = require('../../test/config/test-config');
const store = require('../../test/fixtures/store');
const getApp = require('../app');
const User = require('../types/user');
const eventBus = new EventEmitter();
const currentUser = new User({ id: 1337, email: 'test@mail.com' });
function getSetup() {
const base = `/random${Math.round(Math.random() * 1000)}`;
const stores = store.createStores();
const config = createTestConfig({
server: { baseUriPath: base },
preHook: a => {
a.use((req, res, next) => {
req.user = currentUser;
next();
});
},
});
const services = createServices(stores, config);
const app = getApp(config, stores, services, eventBus);
return {
base,
strategyStore: stores.strategyStore,
request: supertest(app),
destroy: () => {
services.versionService.destroy();
services.clientMetricsService.destroy();
services.apiTokenService.destroy();
},
};
}
test('should logout and redirect', async () => {
expect.assertions(0);
const { base, request, destroy } = getSetup();
await request
.get(`${base}/logout`)
.expect(302)
.expect('Location', `${base}/`);
destroy();
});

View File

@ -0,0 +1,82 @@
import supertest from 'supertest';
import express from 'express';
import { createTestConfig } from '../../test/config/test-config';
import LogoutController from './logout';
import { IAuthRequest } from './unleash-types';
test('should redirect to "/" after logout', async () => {
const baseUriPath = '';
const app = express();
const config = createTestConfig({ server: { baseUriPath } });
app.use('/logout', new LogoutController(config).router);
const request = supertest(app);
expect.assertions(0);
await request
.get(`${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 } });
app.use('/logout', new LogoutController(config).router);
const request = supertest(app);
expect.assertions(0);
await request
.get(`/logout`)
.expect(302)
.expect('Location', `${baseUriPath}/`);
});
test('should set "Clear-Site-Data" header', async () => {
const baseUriPath = '';
const app = express();
const config = createTestConfig({ server: { baseUriPath } });
app.use('/logout', new LogoutController(config).router);
const request = supertest(app);
expect.assertions(0);
await request
.get(`${baseUriPath}/logout`)
.expect(302)
.expect('Clear-Site-Data', '"cookies", "storage"');
});
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();
});
app.use('/logout', new LogoutController(config).router);
const request = supertest(app);
await request.get(`${baseUriPath}/logout`);
expect(fakeSession.destroy.mock.calls.length).toBe(1);
});
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();
});
app.use('/logout', new LogoutController(config).router);
const request = supertest(app);
await request
.get(`/logout`)
.expect(302)
.expect('Location', '/some-other-path');
});

36
src/lib/routes/logout.ts Normal file
View File

@ -0,0 +1,36 @@
import { Response } from 'express';
import { IUnleashConfig } from '../types/option';
import Controller from './controller';
import { IAuthRequest } from './unleash-types';
class LogoutController extends Controller {
private baseUri: string;
constructor(config: IUnleashConfig) {
super(config);
this.baseUri = config.server.baseUriPath;
this.get('/', this.logout);
}
async logout(req: IAuthRequest, res: Response): Promise<void> {
if (req.session) {
// Allow SSO to register custom logout logic.
if (req.session.logoutUrl) {
res.redirect(req.session.logoutUrl);
return;
}
req.session.destroy();
}
if (req.logout) {
req.logout();
}
res.set('Clear-Site-Data', '"cookies", "storage"');
res.redirect(`${this.baseUri}/`);
}
}
module.exports = LogoutController;
export default LogoutController;