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

Add support for req.logout with passport version 0.6.0 and onwards (#2041)

Handle logout based on passport version
This commit is contained in:
Florian Bunsmann 2022-09-13 09:59:34 +02:00 committed by GitHub
parent ee6ec888a7
commit 3a0113d16a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 56 additions and 4 deletions

View File

@ -115,6 +115,42 @@ test('should call destroy on session', async () => {
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();
});
app.use('/logout', new LogoutController(config).router);
const request = supertest(app);
await request.get(`${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();
});
app.use('/logout', new LogoutController(config).router);
const request = supertest(app);
await request.get(`${baseUriPath}/logout`);
expect(logoutFunction).toHaveBeenCalledTimes(1);
expect(logoutFunction).toHaveBeenCalledWith();
});
test('should redirect to alternative logoutUrl', async () => {
const fakeSession = {
destroy: jest.fn(),

View File

@ -1,4 +1,5 @@
import { Response } from 'express';
import { promisify } from 'util';
import { IUnleashConfig } from '../types/option';
import Controller from './controller';
import { IAuthRequest } from './unleash-types';
@ -25,14 +26,23 @@ class LogoutController extends Controller {
res.redirect(req.session.logoutUrl);
return;
}
req.session.destroy();
}
if (req.logout) {
req.logout();
if (this.isReqLogoutWithoutCallback(req.logout)) {
// passport < 0.6.0
req.logout();
} else {
// for passport >= 0.6.0, a callback function is expected as first argument.
// to reuse controller error handling, function is turned into a promise
const logoutAsyncFn = promisify(req.logout).bind(req);
await logoutAsyncFn();
}
}
if (req.session) {
req.session.destroy();
}
res.clearCookie(this.cookieName);
if (this.clearSiteDataOnLogout) {
@ -41,6 +51,12 @@ class LogoutController extends Controller {
res.redirect(`${this.baseUri}/`);
}
private isReqLogoutWithoutCallback(
logout: IAuthRequest['logout'],
): logout is () => void {
return logout.length === 0;
}
}
export default LogoutController;

View File

@ -8,7 +8,7 @@ export interface IAuthRequest<
ReqQuery = any,
> extends Request<PARAM, ResBody, ReqBody, ReqQuery> {
user: User;
logout: () => void;
logout: (() => void) | ((callback: (err?: any) => void) => void);
session: any;
}