@@ -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);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user