Skip to content

Commit d098187

Browse files
committed
Switch to BroadcastChannel
1 parent fde072c commit d098187

File tree

3 files changed

+54
-5
lines changed

3 files changed

+54
-5
lines changed

src/frontend/src/lib/utils/openID.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ import type {
33
OpenIdConfig,
44
} from "$lib/generated/internet_identity_types";
55
import { canisterConfig } from "$lib/globals";
6+
import { fromBase64URL, toBase64URL } from "$lib/utils/utils";
7+
import { Principal } from "@icp-sdk/core/principal";
8+
import { isNullish, nonNullish } from "@dfinity/utils";
69
import {
710
PopupClosedError,
811
REDIRECT_CALLBACK_PATH,
912
redirectInPopup,
10-
} from "$lib/legacy/flows/redirect";
11-
import { fromBase64URL, toBase64URL } from "$lib/utils/utils";
12-
import { Principal } from "@icp-sdk/core/principal";
13-
import { isNullish, nonNullish } from "@dfinity/utils";
13+
} from "../../routes/(new-styling)/callback/utils";
1414

1515
export interface RequestConfig {
1616
// OAuth client ID

src/frontend/src/routes/(new-styling)/callback/+page.svelte

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import { analytics } from "$lib/utils/analytics/analytics";
33
import { onMount } from "svelte";
44
import { goto } from "$app/navigation";
5+
import { sendUrlToOpener } from "./utils";
56
67
analytics.event("page-redirect-callback");
78
@@ -21,6 +22,6 @@
2122
// User was returned here after redirect from a OpenID flow callback,
2223
// these flows are always handled in a popup and the callback url is
2324
// returned to the opener window through the PostMessage API.
24-
window.opener.postMessage(window.location.href, window.location.origin);
25+
sendUrlToOpener();
2526
});
2627
</script>
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
const BROADCAST_CHANNEL = "redirect_callback";
2+
export const REDIRECT_CALLBACK_PATH = "/callback";
3+
4+
export class PopupClosedError extends Error {}
5+
6+
export const redirectInPopup = (url: string): Promise<string> => {
7+
const width = 500;
8+
const height = 600;
9+
const left = (window.innerWidth - width) / 2 + window.screenX;
10+
const top = (window.innerHeight - height) / 2 + window.screenY;
11+
const redirectWindow = window.open(
12+
url,
13+
"_blank",
14+
`width=${width},height=${height},left=${left},top=${top}`,
15+
);
16+
17+
return new Promise<string>((resolve, reject) => {
18+
// We need to throw an error when the window is closed, else the page and
19+
// thus the user will wait indefinitely for a result that never comes.
20+
//
21+
// We can't listen to close events since the window is likely cross-origin,
22+
// so instead we periodically check the closed attribute with an interval.
23+
const closeInterval = setInterval(() => {
24+
if (redirectWindow?.closed === true) {
25+
clearInterval(closeInterval);
26+
reject(new PopupClosedError());
27+
}
28+
}, 500);
29+
// Listen to the popup, we expect a message with the url of the callback,
30+
// after receiving it we can close the popup and resolve the promise.
31+
const channel = new BroadcastChannel(BROADCAST_CHANNEL);
32+
channel.addEventListener("message", (event) => {
33+
if (typeof event.data !== "string") {
34+
return;
35+
}
36+
channel.close();
37+
redirectWindow?.close();
38+
window.focus();
39+
resolve(event.data);
40+
});
41+
});
42+
};
43+
44+
export const sendUrlToOpener = (): void => {
45+
const channel = new BroadcastChannel(BROADCAST_CHANNEL);
46+
channel.postMessage(window.location.href);
47+
channel.close();
48+
};

0 commit comments

Comments
 (0)