From c2b8dada91c90788dcd81a0318c52a66b4b769d1 Mon Sep 17 00:00:00 2001 From: Sergey Ukustov Date: Fri, 29 Sep 2017 19:24:08 +0300 Subject: Add eth_signTypedData handler --- app/scripts/lib/typed-message-manager.js | 108 +++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 app/scripts/lib/typed-message-manager.js (limited to 'app/scripts/lib') diff --git a/app/scripts/lib/typed-message-manager.js b/app/scripts/lib/typed-message-manager.js new file mode 100644 index 000000000..e3efdb45d --- /dev/null +++ b/app/scripts/lib/typed-message-manager.js @@ -0,0 +1,108 @@ +const EventEmitter = require('events') +const ObservableStore = require('obs-store') +const createId = require('./random-id') + + +module.exports = class TypedMessageManager extends EventEmitter { + constructor (opts) { + super() + this.memStore = new ObservableStore({ + unapprovedTypedMessages: {}, + unapprovedTypedMessagesCount: 0, + }) + this.messages = [] + } + + get unapprovedTypedMessagesCount () { + return Object.keys(this.getUnapprovedMsgs()).length + } + + getUnapprovedMsgs () { + return this.messages.filter(msg => msg.status === 'unapproved') + .reduce((result, msg) => { result[msg.id] = msg; return result }, {}) + } + + addUnapprovedMessage (msgParams) { + log.debug(`TypedMessageManager addUnapprovedMessage: ${JSON.stringify(msgParams)}`) + // create txData obj with parameters and meta data + var time = (new Date()).getTime() + var msgId = createId() + var msgData = { + id: msgId, + msgParams: msgParams, + time: time, + status: 'unapproved', + type: 'eth_signTypedData', + } + this.addMsg(msgData) + + // signal update + this.emit('update') + return msgId + } + + addMsg (msg) { + this.messages.push(msg) + this._saveMsgList() + } + + getMsg (msgId) { + return this.messages.find(msg => msg.id === msgId) + } + + approveMessage (msgParams) { + this.setMsgStatusApproved(msgParams.metamaskId) + return this.prepMsgForSigning(msgParams) + } + + setMsgStatusApproved (msgId) { + this._setMsgStatus(msgId, 'approved') + } + + setMsgStatusSigned (msgId, rawSig) { + const msg = this.getMsg(msgId) + msg.rawSig = rawSig + this._updateMsg(msg) + this._setMsgStatus(msgId, 'signed') + } + + prepMsgForSigning (msgParams) { + delete msgParams.metamaskId + return Promise.resolve(msgParams) + } + + rejectMsg (msgId) { + this._setMsgStatus(msgId, 'rejected') + } + + // + // PRIVATE METHODS + // + + _setMsgStatus (msgId, status) { + const msg = this.getMsg(msgId) + if (!msg) throw new Error('TypedMessageManager - Message not found for id: "${msgId}".') + msg.status = status + this._updateMsg(msg) + this.emit(`${msgId}:${status}`, msg) + if (status === 'rejected' || status === 'signed') { + this.emit(`${msgId}:finished`, msg) + } + } + + _updateMsg (msg) { + const index = this.messages.findIndex((message) => message.id === msg.id) + if (index !== -1) { + this.messages[index] = msg + } + this._saveMsgList() + } + + _saveMsgList () { + const unapprovedTypedMessages = this.getUnapprovedMsgs() + const unapprovedTypedMessagesCount = Object.keys(unapprovedTypedMessages).length + this.memStore.updateState({ unapprovedTypedMessages, unapprovedTypedMessagesCount }) + this.emit('updateBadge') + } + +} -- cgit v1.2.3 From 9bc80d998eda937e3a8f95fa5e04fcba66e8a6f8 Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Thu, 5 Oct 2017 14:39:35 -0700 Subject: Add signTypedData input validations --- app/scripts/lib/typed-message-manager.js | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'app/scripts/lib') diff --git a/app/scripts/lib/typed-message-manager.js b/app/scripts/lib/typed-message-manager.js index e3efdb45d..e041ae9f3 100644 --- a/app/scripts/lib/typed-message-manager.js +++ b/app/scripts/lib/typed-message-manager.js @@ -1,6 +1,7 @@ const EventEmitter = require('events') const ObservableStore = require('obs-store') const createId = require('./random-id') +const assert = require('assert') module.exports = class TypedMessageManager extends EventEmitter { @@ -23,6 +24,8 @@ module.exports = class TypedMessageManager extends EventEmitter { } addUnapprovedMessage (msgParams) { + this.validateParams(msgParams) + log.debug(`TypedMessageManager addUnapprovedMessage: ${JSON.stringify(msgParams)}`) // create txData obj with parameters and meta data var time = (new Date()).getTime() @@ -41,6 +44,14 @@ module.exports = class TypedMessageManager extends EventEmitter { return msgId } + validateParams (params) { + assert.equal(typeof params, 'object', 'Params should ben an object.') + assert.ok('data' in params, 'Params must include a data field.') + assert.ok('from' in params, 'Params must include a from field.') + assert.ok(Array.isArray(params.data), 'Data should be an array.') + assert.equal(typeof params.from, 'string', 'From field must be a string.') + } + addMsg (msg) { this.messages.push(msg) this._saveMsgList() -- cgit v1.2.3 From a1696f89a8764f17c10298a45160abf8fc7dce5e Mon Sep 17 00:00:00 2001 From: Sergey Ukustov Date: Sat, 7 Oct 2017 00:38:13 +0300 Subject: Validate data format for eth_signTypedData --- app/scripts/lib/typed-message-manager.js | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'app/scripts/lib') diff --git a/app/scripts/lib/typed-message-manager.js b/app/scripts/lib/typed-message-manager.js index e041ae9f3..8b760790e 100644 --- a/app/scripts/lib/typed-message-manager.js +++ b/app/scripts/lib/typed-message-manager.js @@ -2,6 +2,7 @@ const EventEmitter = require('events') const ObservableStore = require('obs-store') const createId = require('./random-id') const assert = require('assert') +const sigUtil = require('eth-sig-util') module.exports = class TypedMessageManager extends EventEmitter { @@ -50,6 +51,9 @@ module.exports = class TypedMessageManager extends EventEmitter { assert.ok('from' in params, 'Params must include a from field.') assert.ok(Array.isArray(params.data), 'Data should be an array.') assert.equal(typeof params.from, 'string', 'From field must be a string.') + assert.doesNotThrow(() => { + sigUtil.typedSignatureHash(params.data) + }, 'Expected EIP712 typed data') } addMsg (msg) { -- cgit v1.2.3