-
Notifications
You must be signed in to change notification settings - Fork 75
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This allows the user to log in via a popup window opened from within the Zupass embedded iframe. On visiting a Zapp for the first time, the user is asked to connect to Zupass by clicking a button, which causes a popup window to open. If the user is already logged in to Zupass in another tab, then the popup window will pick up the authentication state from that other session, and forward the user's sync key back to the iframe, which will use it to log in. If the user is not already logged in to Zupass in another tab, then they can provide their email and password in the popup window, and after authenticating the sync key will be sent to the iframe. Three failure cases are covered: 1) If the browser blocks popups, a message is shown to the user advising them to change their browser settings and try again 2) If the user closes the popup window before authentication completes, they are informed of this and asked to try again 3) If logging in using the sync key fails, the user is asked to try again
- Loading branch information
Showing
16 changed files
with
417 additions
and
190 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
52 changes: 52 additions & 0 deletions
52
apps/passport-client/components/screens/ZappScreens/AuthenticateIFrameScreen.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import { ReactNode, useEffect, useMemo } from "react"; | ||
import { useLoginIfNoSelf, useSyncKey } from "../../../src/appHooks"; | ||
import { pendingRequestKeys } from "../../../src/sessionStorage"; | ||
import { Spacer } from "../../core"; | ||
import { RippleLoader } from "../../core/RippleLoader"; | ||
import { AppContainer } from "../../shared/AppContainer"; | ||
import { IFrameAuthenticationMessage } from "./ConnectPopupScreen"; | ||
|
||
export function AuthenticateIFrameScreen(): ReactNode { | ||
const encryptionKey = useSyncKey(); | ||
|
||
useLoginIfNoSelf(pendingRequestKeys.authenticateIFrame, "true"); | ||
|
||
// We should only process Zapp approval requests if this window was opened | ||
// by a Zupass iframe. | ||
const isLegitimateOpener = useMemo(() => { | ||
return ( | ||
!!window.opener && | ||
new URL(window.opener.location.href).origin === window.location.origin | ||
); | ||
}, []); | ||
|
||
useEffect(() => { | ||
if (isLegitimateOpener && encryptionKey) { | ||
const chan = new MessageChannel(); | ||
chan.port1.onmessage = (): void => { | ||
// We're going to send the encryption key to the iframe | ||
// When the iframe gets the encryption key, it will | ||
// send a message back to this port, and we can close | ||
// this window | ||
window.close(); | ||
}; | ||
// Zapp is already approved, return to the Zupass iframe | ||
window.opener.postMessage( | ||
{ | ||
type: "auth", | ||
encryptionKey: encryptionKey as string | ||
} satisfies IFrameAuthenticationMessage, | ||
origin, | ||
[chan.port2] | ||
); | ||
window.close(); | ||
} | ||
}, [isLegitimateOpener, encryptionKey]); | ||
|
||
return ( | ||
<AppContainer bg="gray"> | ||
<Spacer h={64} /> | ||
<RippleLoader /> | ||
</AppContainer> | ||
); | ||
} |
Oops, something went wrong.