-
Notifications
You must be signed in to change notification settings - Fork 10
Improve error for Keyguard iframe with unexpected src #397
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 2 commits
ef854ce
289745c
cb5fffe
778b529
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -64,46 +64,53 @@ export class RedirectRequestBehavior extends RequestBehavior { | |
| export class IFrameRequestBehavior extends RequestBehavior { | ||
| private static IFRAME_PATH_SUFFIX = '/request/iframe/'; | ||
|
|
||
| private _iframe: HTMLIFrameElement | null; | ||
| private _client: PostMessageRpcClient | null; | ||
| private _iframeEndpoint: string | null = null; | ||
| private _iframePromise: Promise<HTMLIFrameElement> | null = null; | ||
| private _clientPromise: Promise<PostMessageRpcClient> | null = null; | ||
|
|
||
| constructor() { | ||
| super(BehaviorType.IFRAME); | ||
| this._iframe = null; | ||
| this._client = null; | ||
| } | ||
|
|
||
| public async request(endpoint: string, command: KeyguardCommand, args: any[]): Promise<any> { | ||
| if (this._iframe && this._iframe.src !== `${endpoint}${IFrameRequestBehavior.IFRAME_PATH_SUFFIX}`) { | ||
| throw new Error('Keyguard iframe is already opened with another endpoint'); | ||
| } | ||
|
|
||
| const origin = RequestBehavior.getAllowedOrigin(endpoint); | ||
|
|
||
| if (!this._iframe) { | ||
| this._iframe = await this.createIFrame(endpoint); | ||
| } | ||
| if (!this._iframe.contentWindow) { | ||
| throw new Error(`IFrame contentWindow is ${typeof this._iframe.contentWindow}`); | ||
| } | ||
|
|
||
| if (!this._client) { | ||
| this._client = new PostMessageRpcClient(this._iframe.contentWindow, origin); | ||
| await this._client.init(); | ||
| } | ||
|
|
||
| return await this._client.call(command, ...args); | ||
| const client = await this._getClient(endpoint); | ||
| return client.call(command, ...args); | ||
| } | ||
|
|
||
| public async createIFrame(endpoint: string): Promise<HTMLIFrameElement> { | ||
| return new Promise((resolve, reject) => { | ||
| if (this._iframeEndpoint && this._iframeEndpoint !== endpoint) { | ||
| throw new Error('Keyguard iframe is already opened with another endpoint' + | ||
| `(opened: ${this._iframeEndpoint}, expected: ${endpoint})`); | ||
| } | ||
| this._iframeEndpoint = endpoint; | ||
|
|
||
| this._iframePromise = this._iframePromise || new Promise((resolve, reject) => { | ||
| const $iframe = document.createElement('iframe'); | ||
| $iframe.name = 'NimiqKeyguardIFrame'; | ||
| $iframe.style.display = 'none'; | ||
| document.body.appendChild($iframe); | ||
| $iframe.src = `${endpoint}${IFrameRequestBehavior.IFRAME_PATH_SUFFIX}`; | ||
| $iframe.onload = () => resolve($iframe); | ||
| $iframe.onerror = reject; | ||
|
Comment on lines
93
to
94
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Optional] |
||
| }) as Promise<HTMLIFrameElement>; | ||
| }); | ||
|
|
||
| return this._iframePromise; | ||
| } | ||
|
|
||
| private _getClient(endpoint: string): Promise<PostMessageRpcClient> { | ||
| this._clientPromise = this._clientPromise || new Promise(async (resolve) => { | ||
| const iframe = await this.createIFrame(endpoint); | ||
| if (!iframe.contentWindow) { | ||
| throw new Error(`IFrame contentWindow is ${typeof iframe.contentWindow}`); | ||
| } | ||
|
|
||
| const origin = RequestBehavior.getAllowedOrigin(endpoint); | ||
| const client = new PostMessageRpcClient(iframe.contentWindow, origin); | ||
| await client.init(); | ||
|
|
||
| resolve(client); | ||
|
Comment on lines
+102
to
+111
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wrap in On error also clear the |
||
| }); | ||
|
|
||
| return this._clientPromise; | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In
rejectcase clear the_iframePromiseto avoid that all subsequentcreateIframecalls always fail.