Revert "eliminate racey code"

This reverts commit 907fac9d92.
This commit is contained in:
Fidel Coria
2020-12-22 15:44:42 -06:00
parent 27f2af9354
commit 0836691020
2 changed files with 98 additions and 0 deletions
@@ -135,4 +135,84 @@ describe('showLoginPopup', () => {
expect(addEventListenerSpy).toBeCalledTimes(1);
expect(removeEventListenerSpy).toBeCalledTimes(1);
});
it('should fail if popup is closed', async () => {
const openSpy = jest
.spyOn(window, 'open')
.mockReturnValue({ closed: false } as Window);
const addEventListenerSpy = jest.spyOn(window, 'addEventListener');
const removeEventListenerSpy = jest.spyOn(window, 'removeEventListener');
const popupMock = { closed: false };
openSpy.mockReturnValue(popupMock as Window);
const payloadPromise = showLoginPopup({
url: 'url',
name: 'name',
origin: 'origin',
});
expect(openSpy).toBeCalledTimes(1);
expect(addEventListenerSpy).toBeCalledTimes(1);
expect(removeEventListenerSpy).toBeCalledTimes(0);
const listener = addEventListenerSpy.mock.calls[0][1] as EventListener;
listener({
source: popupMock,
origin: 'origin',
data: {
type: 'config_info',
targetOrigin: 'http://localhost',
},
} as MessageEvent);
setTimeout(() => {
popupMock.closed = true;
}, 150);
await expect(payloadPromise).rejects.toThrow(
'Login failed, popup was closed',
);
expect(openSpy).toBeCalledTimes(1);
expect(addEventListenerSpy).toBeCalledTimes(1);
expect(removeEventListenerSpy).toBeCalledTimes(1);
});
it('should indicate if origin does not match', async () => {
const openSpy = jest
.spyOn(window, 'open')
.mockReturnValue({ closed: false } as Window);
const addEventListenerSpy = jest.spyOn(window, 'addEventListener');
const removeEventListenerSpy = jest.spyOn(window, 'removeEventListener');
const popupMock = { closed: false };
openSpy.mockReturnValue(popupMock as Window);
const payloadPromise = showLoginPopup({
url: 'url',
name: 'name',
origin: 'origin',
});
const listener = addEventListenerSpy.mock.calls[0][1] as EventListener;
listener({
source: popupMock,
origin: 'origin',
data: {
type: 'config_info',
targetOrigin: 'http://differenthost',
},
} as MessageEvent);
setTimeout(() => {
popupMock.closed = true;
}, 150);
await expect(payloadPromise).rejects.toThrow(
'Login failed, Incorrect app origin, expected http://differenthost',
);
expect(openSpy).toBeCalledTimes(1);
expect(addEventListenerSpy).toBeCalledTimes(1);
expect(removeEventListenerSpy).toBeCalledTimes(1);
});
});
+18
View File
@@ -79,6 +79,8 @@ export function showLoginPopup(options: LoginPopupOptions): Promise<any> {
`menubar=no,location=no,resizable=no,scrollbars=no,status=no,width=${width},height=${height},top=${top},left=${left}`,
);
let targetOrigin = '';
if (!popup || typeof popup.closed === 'undefined' || popup.closed) {
reject(new Error('Failed to open auth popup.'));
return;
@@ -94,6 +96,7 @@ export function showLoginPopup(options: LoginPopupOptions): Promise<any> {
const { data } = event;
if (data.type === 'config_info') {
targetOrigin = data.targetOrigin;
return;
}
@@ -114,8 +117,23 @@ export function showLoginPopup(options: LoginPopupOptions): Promise<any> {
done();
};
const intervalId = setInterval(() => {
if (popup.closed) {
const errMessage = `Login failed, ${
targetOrigin !== window.location.origin
? `Incorrect app origin, expected ${targetOrigin}`
: 'popup was closed'
}`;
const error = new Error(errMessage);
error.name = 'PopupClosedError';
reject(error);
done();
}
}, 100);
function done() {
window.removeEventListener('message', messageListener);
clearInterval(intervalId);
}
window.addEventListener('message', messageListener);