Skip to content

Commit

Permalink
fix(wallet): provide origin on webext side instead of empty string
Browse files Browse the repository at this point in the history
  • Loading branch information
davidyuk committed Dec 6, 2022
1 parent 7d003a3 commit 662d8d0
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 35 deletions.
23 changes: 15 additions & 8 deletions examples/browser/wallet-iframe/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -76,20 +76,27 @@ export default {
},
mounted() {
const aeppInfo = {};
const genConfirmCallback = (actionName) => (aeppId) => {
if (!confirm(`Client ${aeppInfo[aeppId].name} with id ${aeppId} want to ${actionName}`)) {
const genConfirmCallback = (actionName) => (aeppId, parameters, origin) => {
if (!confirm([
`Client ${aeppInfo[aeppId].name} with id ${aeppId} at ${origin} want to ${actionName}`,
JSON.stringify(parameters, null, 2),
].join('\n'))) {
throw new RpcRejectedByUserError();
}
};
class AccountMemoryProtected extends MemoryAccount {
async signTransaction(tx, { aeppRpcClientId: id, ...options } = {}) {
if (id != null) genConfirmCallback(`sign transaction ${tx}`)(id);
async signTransaction(tx, { aeppRpcClientId: id, aeppOrigin, ...options } = {}) {
if (id != null) {
genConfirmCallback(`sign transaction ${tx}`)(id, options, aeppOrigin);
}
return super.signTransaction(tx, options);
}
async signMessage(message, { aeppRpcClientId: id, ...options } = {}) {
if (id != null) genConfirmCallback(`sign message ${message}`)(id);
async signMessage(message, { aeppRpcClientId: id, aeppOrigin, ...options } = {}) {
if (id != null) {
genConfirmCallback(`sign message ${message}`)(id, options, aeppOrigin);
}
return super.signMessage(message, options);
}
Expand All @@ -113,8 +120,8 @@ export default {
],
onCompiler: new CompilerHttp('https://v7.compiler.aepps.com'),
name: 'Wallet Iframe',
onConnection: (aeppId, params) => {
if (!confirm(`Client ${params.name} with id ${aeppId} want to connect`)) {
onConnection: (aeppId, params, origin) => {
if (!confirm(`Client ${params.name} with id ${aeppId} at ${origin} want to connect`)) {
throw new RpcConnectionDenyError();
}
aeppInfo[aeppId] = params;
Expand Down
24 changes: 15 additions & 9 deletions examples/browser/wallet-web-extension/src/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,27 @@ import {
} from '@aeternity/aepp-sdk';

const aeppInfo = {};
const genConfirmCallback = (actionName) => (aeppId) => {
if (!confirm(`Client ${aeppInfo[aeppId].name} with id ${aeppId} want to ${actionName}`)) {
const genConfirmCallback = (actionName) => (aeppId, parameters, origin) => {
if (!confirm([
`Client ${aeppInfo[aeppId].name} with id ${aeppId} at ${origin} want to ${actionName}`,
JSON.stringify(parameters, null, 2),
].join('\n'))) {
throw new RpcRejectedByUserError();
}
};

class AccountMemoryProtected extends MemoryAccount {
async signTransaction(tx, { aeppRpcClientId: id, ...options } = {}) {
if (id != null) genConfirmCallback(`sign transaction ${tx}`)(id);
async signTransaction(tx, { aeppRpcClientId: id, aeppOrigin, ...options } = {}) {
if (id != null) {
genConfirmCallback(`sign transaction ${tx}`)(id, options, aeppOrigin);
}
return super.signTransaction(tx, options);
}

async signMessage(message, { aeppRpcClientId: id, ...options } = {}) {
if (id != null) genConfirmCallback(`sign message ${message}`)(id);
async signMessage(message, { aeppRpcClientId: id, aeppOrigin, ...options } = {}) {
if (id != null) {
genConfirmCallback(`sign message ${message}`)(id, options, aeppOrigin);
}
return super.signMessage(message, options);
}

Expand All @@ -41,9 +48,8 @@ const aeSdk = new AeSdkWallet({
id: browser.runtime.id,
type: WALLET_TYPE.extension,
name: 'Wallet WebExtension',
// Hook for sdk registration
onConnection(aeppId, params) {
if (!confirm(`Aepp ${params.name} with id ${aeppId} wants to connect`)) {
onConnection: (aeppId, params, origin) => {
if (!confirm(`Client ${params.name} with id ${aeppId} at ${origin} want to connect`)) {
throw new RpcConnectionDenyError();
}
aeppInfo[aeppId] = params;
Expand Down
3 changes: 2 additions & 1 deletion src/aepp-wallet-communication/connection/BrowserRuntime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ export default class BrowserRuntimeConnection extends BrowserConnection {
super.connect(onMessage, onDisconnect);
this.port.onMessage.addListener((message, port) => {
this.receiveMessage(message);
onMessage(message, port.name, port);
// TODO: make `origin` optional because sender url is not available on aepp side
onMessage(message, port.sender?.url ?? '', port);
});
this.port.onDisconnect.addListener(onDisconnect);
}
Expand Down
45 changes: 28 additions & 17 deletions test/integration/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ const WindowPostMessageFake = (
this.messages.push(msg);
setTimeout(() => {
if (typeof this.listener === 'function') {
this.listener({ data: msg, origin: 'testOrigin', source });
this.listener({ data: msg, origin: 'http://origin.test', source });
}
});
},
Expand Down Expand Up @@ -213,11 +213,19 @@ describe('Aepp<->Wallet', function aeppWallet() {
});

it('Subscribe to address: wallet accept', async () => {
wallet.onSubscription = () => {};
let checkPromise;
wallet.onSubscription = (id, params, origin) => {
checkPromise = Promise.resolve().then(() => {
expect(id.split('-').length).to.be.equal(5);
expect(params).to.be.eql({ type: 'subscribe', value: 'connected' });
expect(origin).to.be.equal('http://origin.test');
});
};
await aepp.subscribeAddress(SUBSCRIPTION_TYPES.subscribe, 'connected');
await aepp.subscribeAddress(SUBSCRIPTION_TYPES.unsubscribe, 'connected');
const subscriptionResponse = await aepp.subscribeAddress(SUBSCRIPTION_TYPES.subscribe, 'connected');

await checkPromise;
subscriptionResponse.subscription.should.be.an('array');
subscriptionResponse.subscription.filter((e) => e === 'connected').length.should.be.equal(1);
subscriptionResponse.address.current.should.be.an('object');
Expand Down Expand Up @@ -250,10 +258,18 @@ describe('Aepp<->Wallet', function aeppWallet() {
});

it('Ask for address: subscribed for accounts -> wallet accept', async () => {
wallet.onAskAccounts = () => {};
let checkPromise;
wallet.onAskAccounts = (id, params, origin) => {
checkPromise = Promise.resolve().then(() => {
expect(id.split('-').length).to.be.equal(5);
expect(params).to.be.equal(undefined);
expect(origin).to.be.equal('http://origin.test');
});
};
const addressees = await aepp.askAddresses();
addressees.length.should.be.equal(2);
addressees[0].should.be.equal(account.address);
await checkPromise;
});

it('Not authorize', async () => {
Expand All @@ -266,7 +282,9 @@ describe('Aepp<->Wallet', function aeppWallet() {
});

it('Sign transaction: wallet deny', async () => {
wallet._resolveAccount().signTransaction = () => {
let origin;
wallet._resolveAccount().signTransaction = (tx, { aeppOrigin }) => {
origin = aeppOrigin;
throw new RpcRejectedByUserError();
};
const tx = await aepp.buildTx(Tag.SpendTx, {
Expand All @@ -277,6 +295,7 @@ describe('Aepp<->Wallet', function aeppWallet() {
});
await expect(aepp.signTransaction(tx)).to.be.eventually
.rejectedWith('Operation rejected by user').with.property('code', 4);
expect(origin).to.be.equal('http://origin.test');
});

it('Sign transaction: fails with unknown error', async () => {
Expand Down Expand Up @@ -346,11 +365,14 @@ describe('Aepp<->Wallet', function aeppWallet() {
});

it('Sign message: rejected', async () => {
wallet._resolveAccount().signMessage = () => {
let origin;
wallet._resolveAccount().signMessage = (message, { aeppOrigin } = {}) => {
origin = aeppOrigin;
throw new RpcRejectedByUserError();
};
await expect(aepp.signMessage('test')).to.be.eventually
.rejectedWith('Operation rejected by user').with.property('code', 4);
expect(origin).to.be.equal('http://origin.test');
});

it('Sign message', async () => {
Expand Down Expand Up @@ -490,7 +512,6 @@ describe('Aepp<->Wallet', function aeppWallet() {
});

describe('New RPC Wallet-AEPP: Bind wallet node to AEPP', () => {
const keypair = generateKeyPair();
let aepp: AeSdkAepp;
let wallet: AeSdkWallet;

Expand Down Expand Up @@ -520,21 +541,11 @@ describe('Aepp<->Wallet', function aeppWallet() {
});

it('Subscribe to address: wallet accept', async () => {
const accounts = {
connected: { [keypair.publicKey]: {} },
current: wallet.addresses().reduce((acc, v) => ({ ...acc, [v]: {} }), {}),
};
wallet.onSubscription = () => accounts;
wallet.onSubscription = () => {};
await aepp.subscribeAddress(SUBSCRIPTION_TYPES.subscribe, 'connected');
await aepp.subscribeAddress(SUBSCRIPTION_TYPES.unsubscribe, 'connected');
const subscriptionResponse = await aepp.subscribeAddress(SUBSCRIPTION_TYPES.subscribe, 'connected');

subscriptionResponse.subscription.should.be.an('array');
subscriptionResponse.subscription.filter((e) => e === 'connected').length.should.be.equal(1);
subscriptionResponse.address.current.should.be.an('object');
Object.keys(subscriptionResponse.address.current)[0].should.be.equal(account.address);
subscriptionResponse.address.connected.should.be.an('object');
Object.keys(subscriptionResponse.address.connected).length.should.be.equal(0);
});

it('Sign by wallet and broadcast transaction by aepp ', async () => {
Expand Down

0 comments on commit 662d8d0

Please sign in to comment.