Skip to content

Commit

Permalink
Fix cross origin iframe bugs (rrweb-io#1093)
Browse files Browse the repository at this point in the history
* fix: error data while recording some websites are integrated  with stripe

These websites will usually have an iframe with src "https://js.stripe.com/v3/m-outer-xxx.html"

* add test case for the bug

* fix: recordCrossOriginIframes: true does not work with pack/unpack fn

1. bugfix
2. add test case
3. add rrweb-all.js to the result of command: bundle:browser
4. make puppeteer headless in CI by default to increase the speed and stability
  • Loading branch information
YunFeng0817 authored Jan 16, 2023
1 parent 57a2e14 commit fc82869
Show file tree
Hide file tree
Showing 8 changed files with 540 additions and 34 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
run: yarn turbo run check-types

- name: Run tests
run: xvfb-run --server-args="-screen 0 1920x1080x24" yarn test
run: PUPPETEER_HEADLESS=true xvfb-run --server-args="-screen 0 1920x1080x24" yarn test

- name: Upload diff images to GitHub
uses: actions/upload-artifact@v3
Expand Down
5 changes: 5 additions & 0 deletions packages/rrweb/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,11 @@ if (process.env.BROWSER_ONLY) {
name: 'rrweb',
pathFn: (p) => p,
},
{
input: './src/entries/all.ts',
name: 'rrweb',
pathFn: toAllPath,
},
{
input: './src/plugins/console/record/index.ts',
name: 'rrwebConsoleRecord',
Expand Down
36 changes: 21 additions & 15 deletions packages/rrweb/src/record/iframe-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,24 +83,30 @@ export class IframeManager {
);
}
private handleMessage(message: MessageEvent | CrossOriginIframeMessageEvent) {
if ((message as CrossOriginIframeMessageEvent).data.type === 'rrweb') {
const iframeSourceWindow = message.source;
if (!iframeSourceWindow) return;
const crossOriginMessageEvent = message as CrossOriginIframeMessageEvent;
if (
crossOriginMessageEvent.data.type !== 'rrweb' ||
// To filter out the rrweb messages which are forwarded by some sites.
crossOriginMessageEvent.origin !== crossOriginMessageEvent.data.origin
)
return;

const iframeEl = this.crossOriginIframeMap.get(message.source);
if (!iframeEl) return;
const iframeSourceWindow = message.source;
if (!iframeSourceWindow) return;

const transformedEvent = this.transformCrossOriginEvent(
iframeEl,
(message as CrossOriginIframeMessageEvent).data.event,
);
const iframeEl = this.crossOriginIframeMap.get(message.source);
if (!iframeEl) return;

if (transformedEvent)
this.wrappedEmit(
transformedEvent,
(message as CrossOriginIframeMessageEvent).data.isCheckout,
);
}
const transformedEvent = this.transformCrossOriginEvent(
iframeEl,
crossOriginMessageEvent.data.event,
);

if (transformedEvent)
this.wrappedEmit(
transformedEvent,
crossOriginMessageEvent.data.isCheckout,
);
}

private transformCrossOriginEvent(
Expand Down
7 changes: 6 additions & 1 deletion packages/rrweb/src/record/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,11 @@ function record<T = eventWithTime>(
e = plugin.eventProcessor(e);
}
}
if (packFn) {
if (
packFn &&
// Disable packing events which will be emitted to parent frames.
!passEmitsToParent
) {
e = (packFn(e) as unknown) as eventWithTime;
}
return (e as unknown) as T;
Expand All @@ -190,6 +194,7 @@ function record<T = eventWithTime>(
const message: CrossOriginIframeMessageEventContent<T> = {
type: 'rrweb',
event: eventProcessor(e),
origin: window.location.origin,
isCheckout,
};
window.parent.postMessage(message, '*');
Expand Down
2 changes: 2 additions & 0 deletions packages/rrweb/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,8 @@ declare global {
export type CrossOriginIframeMessageEventContent<T = eventWithTime> = {
type: 'rrweb';
event: T;
// The origin of the iframe which originally emits this message. It is used to check the integrity of message and to filter out the rrweb messages which are forwarded by some sites.
origin: string;
isCheckout?: boolean;
};
export type CrossOriginIframeMessageEvent = MessageEvent<CrossOriginIframeMessageEventContent>;
Loading

0 comments on commit fc82869

Please sign in to comment.