Skip to content

Commit 47179f7

Browse files
authored
feat(AEX_2): Connect to extension from iframe (#992)
* feat(AEX_2): Add flag for allowing cross origin messages for WindowMessageConnection and Content script bridge Adjust WalletDetector to properly resolve origin and create connnection * feat(AEX_2): Remove check for available network in Wallet `connect` handler * feat(AEX_2): Add auto target detection for BrowserWindowConnection * feat(AEX_2): Adjust helper for multiple browser support * feat(AEX_2): Fix RPC test's * feat(AEX_2): Fix RPC test's
1 parent 87b9ef9 commit 47179f7

File tree

7 files changed

+50
-8
lines changed

7 files changed

+50
-8
lines changed

es/utils/aepp-wallet-communication/connection/browser-window-message.js

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import stampit from '@stamp/it'
2828
import WalletConnection from '.'
2929
import { v4 as uuid } from 'uuid'
3030
import { MESSAGE_DIRECTION } from '../schema'
31+
import { isContentScript, isInIframe } from '../helpers'
3132

3233
/**
3334
* Check if connected
@@ -52,11 +53,12 @@ function connect (onMessage) {
5253
const origin = this.origin
5354
const receiveDirection = this.receiveDirection
5455
const debug = this.debug
56+
const forceOrigin = this.forceOrigin
5557
if (this.listener) throw new Error('You already connected')
5658

5759
this.listener = (msg, source) => {
5860
if (!msg || typeof msg.data !== 'object') return
59-
if (origin && origin !== msg.origin) return
61+
if (!forceOrigin && origin && origin !== msg.origin) return
6062
if (debug) console.log('Receive message: ', msg)
6163
if (msg.data.type) {
6264
if (msg.data.type !== receiveDirection) return
@@ -95,6 +97,16 @@ function sendMessage (msg) {
9597
this.postFn(message)
9698
}
9799

100+
const getTarget = () => {
101+
const isCS = isContentScript()
102+
if (isCS) {
103+
return window
104+
}
105+
// When we is the main page we need to decide the target by our self
106+
// Probably can be implemented some algo for checking DOM for Iframes and somehow decide which Iframe to talk
107+
return isInIframe() ? window.parent : undefined
108+
}
109+
98110
/**
99111
* BrowserWindowMessageConnection
100112
* @function
@@ -111,7 +123,7 @@ function sendMessage (msg) {
111123
* @return {Object}
112124
*/
113125
export const BrowserWindowMessageConnection = stampit({
114-
init ({ connectionInfo = {}, target = window.parent, self = window, origin, sendDirection, receiveDirection = MESSAGE_DIRECTION.to_aepp, debug = false } = {}) {
126+
init ({ connectionInfo = {}, target = getTarget(), self = window, origin, sendDirection, receiveDirection = MESSAGE_DIRECTION.to_aepp, debug = false, forceOrigin = false } = {}) {
115127
if (sendDirection && !Object.keys(MESSAGE_DIRECTION).includes(sendDirection)) throw new Error(`sendDirection must be one of [${Object.keys(MESSAGE_DIRECTION)}]`)
116128
if (!Object.keys(MESSAGE_DIRECTION).includes(receiveDirection)) throw new Error(`receiveDirection must be one of [${Object.keys(MESSAGE_DIRECTION)}]`)
117129
this.connectionInfo = { ...{ id: uuid() }, ...connectionInfo }
@@ -120,6 +132,7 @@ export const BrowserWindowMessageConnection = stampit({
120132
const targetP = target
121133
this.origin = origin
122134
this.debug = debug
135+
this.forceOrigin = forceOrigin
123136
this.sendDirection = sendDirection
124137
this.receiveDirection = receiveDirection
125138
this.subscribeFn = (listener) => selfP.addEventListener('message', listener, false)

es/utils/aepp-wallet-communication/content-script-bridge.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,14 @@ import stampit from '@stamp/it'
3232
* @return {void}
3333
*/
3434
function run () {
35+
const allowCrossOrigin = this.allowCrossOrigin
3536
// Connect to extension using runtime
3637
this.extConnection.connect((msg) => {
3738
this.pageConnection.sendMessage(msg)
3839
})
3940
// Connect to page using window.postMessage
4041
this.pageConnection.connect((msg, origin, source) => {
41-
if (source !== window) return
42+
if (!allowCrossOrigin && source !== window) return
4243
this.extConnection.sendMessage(msg)
4344
})
4445
}
@@ -67,10 +68,11 @@ function stop () {
6768
* @return {ContentScriptBridge}
6869
*/
6970
export const ContentScriptBridge = stampit({
70-
init ({ pageConnection, extConnection }) {
71+
init ({ pageConnection, extConnection, allowCrossOrigin = false }) {
7172
if (!window) throw new Error('Window object not found, you can run bridge only in browser')
7273
if (!pageConnection) throw new Error('pageConnection required')
7374
if (!extConnection) throw new Error('extConnection required')
75+
this.allowCrossOrigin = allowCrossOrigin
7476
this.pageConnection = pageConnection
7577
this.extConnection = extConnection
7678
},

es/utils/aepp-wallet-communication/helpers.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,22 @@
44
/* eslint-disable no-undef */
55
import { isMemoryAccount } from '../../account/selector'
66

7+
const isWeb = () => location && location.protocol && location.protocol.startsWith('http')
8+
79
export const getBrowserAPI = (force = false) => {
810
if (chrome === Object(chrome) && chrome.runtime) return chrome
911
if (browser === Object(browser) && browser.runtime) return browser
1012
if (!force) throw new Error('Browser is not detected')
1113
return {}
1214
}
1315

16+
const isExtensionContext = () => {
17+
const browser = getBrowserAPI()
18+
return typeof browser === 'object' && browser && typeof browser.extension === 'object'
19+
}
20+
21+
export const isContentScript = () => isExtensionContext() && isWeb()
22+
1423
export const isInIframe = () => window !== window.parent
1524

1625
export const getWindow = () => {

es/utils/aepp-wallet-communication/wallet-detector.js

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,20 @@ import { isInIframe } from './helpers'
3131

3232
const wallets = {}
3333

34+
const getOrigin = ({ isExtension, origin }) => {
35+
if (isExtension) {
36+
return window.origin
37+
}
38+
return origin
39+
}
40+
41+
const getTarget = ({ isExtension, source }) => {
42+
if (isExtension) {
43+
return source
44+
}
45+
return isInIframe() ? window.parent : source
46+
}
47+
3448
const handleDetection = (onDetected) => ({ method, params }, origin, source) => {
3549
if (!method || !params) return
3650
const ifExist = Object.prototype.hasOwnProperty.call(wallets, params.id)
@@ -40,12 +54,14 @@ const handleDetection = (onDetected) => ({ method, params }, origin, source) =>
4054
async getConnection () {
4155
// if detect extension wallet or page wallet
4256
const isExtension = this.type === 'extension'
57+
const origin = getOrigin({ isExtension, origin: this.origin })
58+
const target = getTarget({ isExtension, source })
4359
return BrowserWindowMessageConnection({
4460
connectionInfo: this,
45-
origin: isExtension ? window.origin : this.origin,
4661
sendDirection: isExtension ? MESSAGE_DIRECTION.to_waellet : undefined,
4762
receiveDirection: isExtension ? MESSAGE_DIRECTION.to_aepp : undefined,
48-
target: isInIframe() ? window.parent : source
63+
target,
64+
origin
4965
})
5066
}
5167
}

examples/browser/extension/src/manifest.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@
3131
],
3232
"js": [
3333
"inject.bundle.js"
34-
]
34+
],
35+
"all_frames": true
3536
}
3637
]
3738
}

examples/browser/vuejs/connect-two-ae/aepp/src/components/Home.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@
329329
async created () {
330330
// Open iframe with Wallet if run in top window
331331
window !== window.parent || await this.getReverseWindow()
332-
//
332+
333333
this.client = await RpcAepp({
334334
name: 'AEPP',
335335
nodes: [{ name: 'test-net', instance: await Node({ url: NODE_URL, internalUrl: NODE_INTERNAL_URL }) }],

test/integration/rpc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,5 +674,6 @@ describe('Aepp<->Wallet', function () {
674674
const getConnections = (direct) => {
675675
global.chrome = { runtime: {} }
676676
global.window = { location: { origin: '//test' } }
677+
global.location = { protocol: 'http://test.com' }
677678
return getFakeConnections(direct)
678679
}

0 commit comments

Comments
 (0)