Skip to content
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

fix: use stringified object when communicating from provider to client #26

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions src/controllers/AVMWebClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,22 +62,31 @@ export default class AVMWebClient extends BaseController<IAVMWebClientConfig> {
): string {
const _functionName: string = 'addListener';
const listener: TClientCustomEventListener = (event) => {
let detail: ResponseMessageWithError | ResponseMessageWithResult<Result>;

try {
detail = JSON.parse(event.detail); // the event.detail should be a stringified object
} catch (error) {
console.error(`${AVMWebClient.name}#${_functionName}:`, error);

return;
}

// if the request event is not known, ignore
if (!this.requestIds.includes(event.detail.requestId)) {
if (!this.requestIds.includes(detail.requestId)) {
return;
}

this.logger.debug(
`${AVMWebClient.name}#${_functionName}: received response event:`,
event.detail
detail
);

callback({
...event.detail,
error: (event.detail as ResponseMessageWithError).error || null,
...detail,
error: (detail as ResponseMessageWithError).error || null,
method,
result:
(event.detail as ResponseMessageWithResult<Result>).result || null,
result: (detail as ResponseMessageWithResult<Result>).result || null,
});
};
const listenerID: string = uuid();
Expand Down
62 changes: 38 additions & 24 deletions src/controllers/AVMWebProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ export default class AVMWebProvider extends BaseController<IAVMWebProviderConfig
return listenerID;
}

/**
* Dispatches an event to the web page with the result/error from the `options.callback` function.
* NOTE: the event uses the detail property of the `CustomEvent` but due to Firefox's limitation of only allowing
* non-string properties, the response message MUST be a serializable object as it will be stringified to allow
* transport.
* @see {@link https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Sharing_objects_with_page_scripts}
* @private
*/
private async sendResponseMessage<
Params = TRequestParams,
Result = TResponseResults,
Expand All @@ -107,13 +115,15 @@ export default class AVMWebProvider extends BaseController<IAVMWebProviderConfig

// dispatch a response event with the result
window.dispatchEvent(
new CustomEvent<ResponseMessageWithResult<Result>>(reference, {
detail: new ResponseMessageWithResult<Result>({
id,
reference,
requestId: requestMessage.id,
result,
}),
new CustomEvent(reference, {
detail: JSON.stringify(
new ResponseMessageWithResult<Result>({
id,
reference,
requestId: requestMessage.id,
result,
})
),
})
);

Expand All @@ -128,13 +138,15 @@ export default class AVMWebProvider extends BaseController<IAVMWebProviderConfig
// if we have an arc-0027 error, send it in the response
if ((error as BaseARC0027Error).code) {
window.dispatchEvent(
new CustomEvent<ResponseMessageWithError>(reference, {
detail: new ResponseMessageWithError({
error,
id,
reference,
requestId: requestMessage.id,
}),
new CustomEvent(reference, {
detail: JSON.stringify(
new ResponseMessageWithError({
error,
id,
reference,
requestId: requestMessage.id,
})
),
})
);

Expand All @@ -143,16 +155,18 @@ export default class AVMWebProvider extends BaseController<IAVMWebProviderConfig

// otherwise, wrap the message in an unknown error
window.dispatchEvent(
new CustomEvent<ResponseMessageWithError>(reference, {
detail: new ResponseMessageWithError({
error: new ARC0027UnknownError({
message: error.message,
providerId: this.config.providerId,
}),
id,
reference,
requestId: requestMessage.id,
}),
new CustomEvent(reference, {
detail: JSON.stringify(
new ResponseMessageWithError({
error: new ARC0027UnknownError({
message: error.message,
providerId: this.config.providerId,
}),
id,
reference,
requestId: requestMessage.id,
})
),
})
);

Expand Down
15 changes: 2 additions & 13 deletions src/types/TClientCustomEventListener.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,5 @@
// messages
import {
ResponseMessageWithError,
ResponseMessageWithResult,
} from '@app/messages';

// types
import type TResponseResults from './TResponseResults';

type TClientCustomEventListener<Result = TResponseResults> = (
event: CustomEvent<
ResponseMessageWithError | ResponseMessageWithResult<Result>
>
type TClientCustomEventListener = (
event: CustomEvent<string>
) => Promise<void> | void;

export default TClientCustomEventListener;